Как сделать что-то для каждого входного текстового файла

Скажем, я прочитал следующую информацию, хранящуюся в трех разных текстовых файлах (может быть намного больше)

Файл 1

1 2 rt 45
2 3 er 44

Файл 2

rf r 4 5
3 er 4 t
er t yu 4

Файл 3

er tyu 3er 3r
der 4r 5e
edr rty tyu 4r
edr 5t yt5 45

Когда я читаю эту информацию, я хочу, чтобы она печатала эту информацию из этих двух файлов в отдельные массивы, так как сейчас они распечатываются в одно и то же время.

Теперь у меня есть этот скрипт, распечатывающий всю информацию одновременно

{
    TESTd[NR-1] = $2; g++
}   
END {           
   for (i = 0 ; i <= g-1; i ++ ) {
        print "            [\"" TESTd[i] "\"]"

     }
     print "            _____"
}

Но есть ли способ читать несколько файлов и делать это для каждого текстового файла? Например, вместо получения этого вывода при выполнении awk -f test.awk 1.txt 2.txt 3.txt

    ["2"]
    ["3"]
    ["r"]
    ["er"]
    ["t"]
    ["tyu"]
    ["4r"]
    ["rty"]
    ["5t"]
    _____

Я получаю этот вывод

    ["2"]
    ["3"]
    _____
    ["r"]
    ["er"]
    ["t"]
    _____
    ["tyu"]
    ["4r"]
    ["rty"]
    ["5t"]
    _____

И чтение в каждом файле за раз предпочтительно не вариант, так как у меня будет около 30 текстовых файлов.

EDIT________________< em>________________________________________________

Я хочу сделать это в awk, если это возможно, потому что я собираюсь сделать что-то вроде этого

{
    PRINTONCE[NR-1] = $2; g++
    PRINTONEATTIME[NR-1] = $3
}
END { 
            #Do this for all arguments once
        for (i = 0 ; i <= g-1; i ++ ) {
             print "            [\"" PRINTONCE[i] "\"] \n"
        }
        print "            _____"
            #Do this for loop for every .txt file that is read in as an argument
              #for(j=0;j<args.length;j++){
        for (i = 0 ; i <= g-1; i ++ ) {
             print "            [\"" PRINTONEATTIME[i] "\"] \n"
        }
        print "            _____"
}

person johannes    schedule 30.06.2011    source источник
comment
Что-то вроде for(i=0; i‹args.length;i++){   -  person johannes    schedule 30.06.2011


Ответы (4)


Насколько я понимаю, у вас есть работающий awk-скрипт, и вы хотите запустить этот awk-скрипт для многих файлов и хотите, чтобы их вывод имел новую строку (или _) между ними, чтобы вы могли различать, какие вывод из какого файла.

Попробуйте этот скрипт bash: -

dir=~/*.txt #all txt files in ~(home) directory
for f in $dir
do
    echo "File is $f"
    awk 'BEGIN{print "Hello"}' $f #your awk code will take $f file as input.
    echo "------------------"; echo;
done

Кроме того, если вы не хотите делать это со всеми файлами, вы можете написать цикл for как for f in 1.txt 2.txt 3.txt.

person Priyank Bhatnagar    schedule 30.06.2011
comment
Не удалось заставить его работать, когда я это делаю, я получаю следующую ошибку selnc210:/AWK›chmod +x he.sh selnc210:/AWK./he.sh ./he.sh: команда не найдена. И файл he.sh содержит именно то, что вы написали - person johannes; 30.06.2011
comment
Это правильно и неправильно, у меня есть скрипт awk, который работает, и я хочу сделать только одну его часть для такого количества файлов, которое он принимает в качестве аргумента, остальное все работает правильно, пожалуйста, посмотрите на редактирование для примера, Я хочу сделать только один цикл для всех файлов =) - person johannes; 30.06.2011
comment
@johannes Сценарий работает в моей системе, вы пытались изменить путь к нужному каталогу? И какая именно ошибка появляется? Я запускаю свои сценарии с помощью bash. И я не понимаю вашу правку с вымышленным кодом. Я видел образец вывода, который вы предоставили, и вывод, который вы хотите. Может быть, вы можете разбить свой awk-скрипт на две части: одну, которую вы хотите сделать со всеми файлами, и другую, которая работает нормально. - person Priyank Bhatnagar; 30.06.2011
comment
Как изменить путь к каталогу? Просто пишет, что команда не найдена. . И что я должен написать при вызове bash-скрипта, я сейчас делаю chmod +x he.sh, а затем ./he.sh - person johannes; 30.06.2011
comment
@johannes: Если ваша текущая оболочка не bash, она настроит скрипт в этой оболочке. Попробуйте bash he.sh , также, если единственная ошибка, которая возникает, это команда не найдена, то вы, вероятно, пропустили ./, иначе это невозможно. В первой строке есть переменная dir, измените ее значение на ваш рабочий каталог, но я не думаю, что здесь проблема. - person Priyank Bhatnagar; 30.06.2011

Если вы не хотите делать это напрямую в awk. Вы можете назвать это так, например, в bash или zsh:

for fic in test*.txt; awk -f test.awk $fic
person yogsototh    schedule 30.06.2011
comment
Должен ли я распечатать это в командной строке или поместить в отдельный файл, я не совсем с вами, не могли бы вы дать немного более развернутый ответ, который сделал бы мой день. Спасибо =) - person johannes; 30.06.2011

Это довольно просто сделать прямо в awk:

# define a function to print out the array
function dump(array, n) {
    for (i = 0 ; i <= n-1; i ++ ) {
        print "            [\"" array[i] "\"]"
    }
    print "            _____"
}

# dump and reset when starting a new file
FNR==1 && NR!=1 {
    dump(TESTd, g)
    delete TESTd
    g = 0
}
# add data to the array
{
    TESTd[FNR-1] = $2; g++
}
# dump at the end
END {
    dump(TESTd, g)
}

Н.Б. использование delete TESTd является нестандартной функцией gawk, но вопрос помечен как gawk, поэтому я предположил, что его можно использовать.

В качестве альтернативы вы можете использовать один или несколько из ARGIND, ARGV, ARGC или FILENAME, чтобы различать разные файлы.

Или, как было предложено в разделе https://stackoverflow.com/a/10691259/981959, с gawk 4 вы можете использовать Группа ENDFILE вместо END в оригинале:

{
    TESTd[FNR-1] = $2; g++
}
ENDFILE {
    for (i = 0 ; i <= g-1; i ++ ) {
        print "            [\"" TESTd[i] "\"]"
    }
    print "            _____"
    delete TESTd
    g = 0
}
person Jonathan Wakely    schedule 26.06.2012

Напишите сценарий оболочки bash или базовый сценарий оболочки. Попробуйте вставить ниже в test.sh. Затем вызовите /bin/sh test.sh или /bin/bash test.sh, посмотрите, какой из них будет работать.

for f in *.txt
do
  echo "File is $f"
  awk -F '\t' 'blah blah' $f >> output.txt
done

Или напишите сценарий оболочки bash для вызова вашего сценария awk.

for f in *.txt
do
  echo "File is $f"
  /bin/sh yourscript.sh
done
person trillions    schedule 08.07.2012