Awk перевернуть обе строки и слова - PullRequest
7 голосов
/ 27 марта 2012

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

«Файл1» для обратного:

АБ, БК, СС

foo do as

И вывод на печать «File1» должен быть таким:

как и foo

куб.см. а.а.

Я пробовал это для обратного слова в каждой строке:

for (i=NF; i>1; i--) printf("%s ",$i); printf("%s\n",$1)

но если я хочу напечатать перевернутые строки, я должен сделать это

{a[NR]=$0
}END{for(i=NR; i; i--) print a[i]}

Мне нужно работать с двумя файлами с этой командой в терминале:

awk -f commandFile FileToBePrinted

Проблема в том, что я новичок во всем этом и не знаю, как объединить эти два. Спасибо!

Ответы [ 3 ]

3 голосов
/ 27 марта 2012

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

У вас есть код, который вам нужен, вам просто нужно немного изменить его.

cat file1
aa bb cc
foo do as

cat commandFile

function reverse( line ) {
  n=split(line, tmpLine)
  for (j=n; j>0; j--) {
    printf("%s ",tmpLine[j] )
  }

}
# main loop
{ a[NR]=$0 }

# print reversed array
END{ for(i=NR; i>0; i--) printf( "%s\n",  reverse(a[i]) ) }

Запуск

 awk -f commandFile file1

выход

as do foo
cc bb aa

Было сделано несколько небольших изменений, которые я использовал, используя n=split(line, tmpLine) ... print tmpLine[j], это распространенный метод анализа строки ввода в функции для ее распечатки. Я не думаю, что переменные $ 1 имеют область видимости из значения, переданного из массива (ваше значение a [i]), поэтому я изменил его на split..tmpLine [j]. Я также обнаружил, что переменная 'i' из секции END была сохранена в области видимости в функции reverse, поэтому я изменил ее на j, чтобы устранить неоднозначность ситуации.


Мне пришлось кое-что выяснить, поэтому ниже приведена отладочная версия, которую я использовал.

Если у вас будет доступ к gawk, то вы хорошо научитесь пользоваться доступным отладчиком. Если вы используете awk / gawk / nawk в системах без отладчика, то это один из способов понять, что происходит в вашем коде. Если вы перенаправляете вывод своих программ в файл или канал, и если ваша система поддерживает нотацию "/ dev / stderr", вы можете напечатать там строки отладки, т.е.

 #dbg print "#dbg0:line=" line > "/dev/stderr"

В некоторых системах есть другие нотации для доступа к stderr, поэтому, если вы будете делать это много, стоит выяснить, что доступно.

cat commandFile.debug
function reverse( line ) {
  n=split(line, tmpLine)
  #dbg print "#dbg0:line=" line
  #dbg print "#dbg1:n=" n "\tj=" j "\ttmpLine[j]=" tmpLine[j]
  for (j=n; j>0; j--) {
    #dbg print "#dbg2:n=" n "\tj=" j "\ttempLine[j]=" tmpLine[j]
    printf("%s ",tmpLine[j] )
  }

}
# main loop
{ a[NR]=$0 }

# print reversed array
#dbg END{ print "AT END";  for(i=NR; i>0; i--) printf( "#dbg4:i=%d\t%s\n%s\n", i, a[i] , reverse(a[i])
 ) }
END{ for(i=NR; i>0; i--) printf( "%s\n",  reverse(a[i]) ) }

Надеюсь, это поможет.

2 голосов
/ 27 марта 2012

используйте tac , чтобы повернуть строки в файле, а затем awk, чтобы изменить слова.

tac filename | awk '{for (i=NF; i>1; i--) printf("%s ",$i); printf("%s\n",$1)}'

Вы также можете использовать что-то вроде Perl со встроенными функциями обращения к списку:

tac filename | perl -lane 'print join(" ", reverse(@F))'
2 голосов
/ 27 марта 2012
awk '
{
    x=reverse($0) (x?"\n":"") x
}

END{
    print x
}

function reverse(s,    p)
{
    for(i=length(s);i>0;i--)
        p=p substr(s,i,1)
    return p
}' File1
...