Как удалить CRLF из столбца awk $NF

Прежде всего, как уже отмечали другие, ваша команда cdбесполезна, так как это происходит в контексте оболочки, которая немедленно завершает работу. Но в целом вопрос имеет смысл. Что вам нужно, так это способ заключать в кавычки произвольную строку , чтобы ее можно было использовать в контексте, где она будет интерпретироваться как строка -в кавычках. У меня есть пример этого на моей странице sh трюки :

.

quote () { printf %s\\n "$1" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/'/" ; }

С помощью этой функции вы можете:

myvar="/path to/my directory"
sudo bash -c "cd $(quote "$myvar")"

1
24.01.2020, 09:05
2 ответа

awk не идентифицирует ^Mбуквально, он идентифицирует его как шаблон CRLF \r\n, поэтому ваш sub()может использовать представление символа CR напрямую, как показано ниже. Также вам не нужно проверять, содержит ли поле символ, и делать замену. Функции замены просто ничего не делают, если указанный шаблон не найден. Итак, все, что вам нужно, это заменить CR только в последнем столбце.

awk '{ sub("\r", "", $NF); print $NF }' 

Если необходимо заменить несколько столбцов, переключите $NFна нужный столбец.

Если вы делаете это в цикле для всех столбцов до конца файла, просто выполните

awk '{ for(i=6; i<=NF ; i++) { sub("\r", "", $i); printf "%s ", $i; } }'

Также файл может иметь только крайние NFстолбцы, а $NFявляется последним значением столбца. Измените цикл так, чтобы он выполнялся до NF, чтобы получить доступ к последнему значению столбца.

1
27.01.2020, 23:17

Учитывая несколько реализаций awk, включая GNU awk, mawkи busybox awk(, 3 реализации, обычно встречающиеся в системах на базе Linux -, Cygwin по умолчанию является GNU awk, я полагаю ), RSразделитель входных записей может быть регулярным выражением (в отличие от одиночного символа в POSIX ).

В них можно сделать:

awk -v RS='\r\n' '{print $NF}' < your-file.msdos

для обработки этих файлов или:

awk -v RS='\r?\n' '{print $NF}' < your-file.msdos-or-unix

, чтобы иметь возможность обрабатывать оба файла с разделителями \nили разделителями \r\n.

Некоторые файлы MS -DOS также имеют тенденцию иметь последнюю строку без разделителя -, но awkтакже исправит это при выводе, поскольку добавляет разделитель выходных записей (ORS, который остается \nздесь )ко всем записям при печати.

Что касается разделения полей по умолчанию в awk, вы также обнаружите, что между реализациями существуют различия. POSIX говорит, что он должен быть разделен на последовательности из пробелов , с удалением начальных и конечных пробелов.Понятие пробела зависит от локали и включает как минимум SPC и TAB. Вы обнаружите, что многие реализации awkограничивают его только SPC и TAB независимо от локали, многие также добавляют NL (только в том случае, если разделитель записей не является новой строкой ).

busyboxawk включает все пробелы ASCII, включая CR, FF, VT. Так в busybox awkполя по умолчанию никогда не содержат CR. Вы можете добиться такого же поведения с GNU awk, выполнив gawk -v 'FPAT=[^[:space:]]', где поля затем определяются как последовательности не -пробелов.

Еще несколько замечаний:

  • избегайте циклов оболочки для обработки текста , особенно здесь, поскольку вы уже используете awk, который является одним из правильных инструментов для обработки текста.
  • не используйте echoдля произвольных данных
  • первый аргумент printf— это формат, вы не хотите использовать там произвольные данные. Используйте printf "%s", $3, если вы хотите напечатать $3без добавления ORS, а не printf $3.
  • printf ""не является -оп. Это ничего не делает. Если вы хотите напечатать новую строку, используйте printf "\n"или print ""(, последний печатает ORS, новая строка по умолчанию ).
5
27.01.2020, 23:17

Теги

Похожие вопросы