Как «сделать что-то» для каждого входного текстового файла - PullRequest
1 голос
/ 30 июня 2011

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

Файл 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_ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __

Я хочу сделать это в 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 "            _____"
}

Ответы [ 4 ]

1 голос
/ 30 июня 2011

Из того, что я понимаю, у вас есть скрипт 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.

0 голосов
/ 09 июля 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
0 голосов
/ 27 июня 2012

Это довольно просто сделать прямо в 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)
}

N.B. использование 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
}
0 голосов
/ 30 июня 2011

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

for fic in test*.txt; awk -f test.awk $fic
...