Следующий код обрабатывает имена файлов, которые содержат встроенные новые строки, я поместил сценарий полной версии на paste.ubuntu. Это проверяет на существование и соответствие размерам... Код для генерации данных тестирования также включен там.
# This lists the original fully-qualified filename,
# and its would-be counterpart (assuming it exists)
unset a i
while IFS= read -r -d $'\0' relf; do
printf "%s\n$s" "$PWD${relf:1}" "$(dirname "$(dirname "$PWD")")${relf:1}"
done < <(find . -type f \! -name '.' -name '*' -print0)
Вот демонстрационный вывод (упомянутой выше) полной версии, где один файл отсутствует, и у другого есть другой размер файла к оригиналу
WARNING -----
NOT in target ./file1
ok --------
sizes match ./c/file4-in-subdir
WARNING ------
size mis-match ./file3 is triple-spaced
ok --------
sizes match ./file2
has newline!
Это походит awk
был бы лучший выбор для Ваших потребностей, поскольку эти проблемы не существуют вследствие того, что он может использовать поля и записи:
x=$(awk '/some-pattern/ { sub(/\r$/, "") ; printf("%s", $NF) ; exit }' some-file)
Замена избегает Вашей проблемы с окончаниями строки CRLF.
sub(/\r$/, "")
удаляет запаздывание CR, если это существует. Как awk
обработки \n
как запись (строка) разделитель, Вы не должны разделять его, поскольку это не находится в данных, посмотревших на.
printf("%s", $NF)
печатает заключительное поле ($NF
) без запаздывающей новой строки (print
и некоторый другой awk
функции добавляют новую строку по умолчанию).
exit
происходит после первых двух действий - это - эквивалент m1
в Вашем grep
командная строка. Это гарантирует это awk
выходы после выполнения предыдущих двух команд - и начиная с этих команд выпущены на соответствие, и awk оценивает данные способом FIFO, это только распечатает первое соответствие.
``
или $()
удалит новую строку из конца, но сделать это программно, использовать tr
.
grep -m1 'some-pattern' some-file | sed -n 's/.* //p' | tr -d '\012\015'
Это удалит возврат каретки и/или новую строку от строки.
То, что могло бы быть проблемой, - то, как Вы затем производите результат. Например, по умолчанию, echo
добавляет новая строка. Можно хотеть использовать echo -n
или printf
.
-m1
гарантирует, что существует только один вывод строки, который, по всей вероятности, имел бы возвратом каретки в конце.
– Arcege
03.03.2012, 04:23
tr
... интересный, работы и на LF и на файлах CRLF. Я думал бы \010\013
по некоторым причинам, и также \f\r
работы правильно. О результате: Я на самом деле не помещаю вывод в переменную, но как переменная, включенная в $()
в шаблоне для grep
соответствие - some pipe | grep -o " $(...) "
. Спасибо за
– zetah
03.03.2012, 04:37
Я предпочитаю этот путь
grep -m1 'some-pattern' some-file | sed -n 's/.* //p' | tr -d '\n'
Это работает на меня:
grep -m1 'some-pattern' some-file | sed -n 's/.* //p' | tr -d "\n" | tr -d "\r"
Почему не просто позволенный sed
сделайте [\r\f]
очистка:
# using Bash's $'string' idiom (that decodes ANSI C escape sequences)
# cf. http://wiki.bash-hackers.org/syntax/quoting#ansi_c_like_strings
- X="$(grep -m1 'some-pattern' some-file | sed -n 's/.* //p')"
+ X="$(grep -m1 'some-pattern' some-file | sed -n -e $'s/[\r\f]*$//' -e 's/.* //p')"
Ваш второй подход испытывает недостаток в финале regex для ловли запаздывания CR, \r
.
# sample code to remove trailing \r with sed
# cf. http://en.wikipedia.org/wiki/Regular_expression#POSIX_character_classes
printf 'a b c\r' | sed -n 's/^.* \([[:alpha:]]\{1,\}\)/\1/p' | od -c
printf 'a b c\r' | sed -n 's/^.* \([[:alpha:]]\{1,\}\)[[:space:]]*/\1/p' | od -c
# keeps trailing space after c
printf 'a b c \r' | sed -n 's/^.* \([[:alpha:] ]\{1,\}\)[[:space:]]*/\1/p' | od -b
Обычная версия GREP (включая GREP -P) всегда выводит канал канала с его совпадением, поэтому, если у вас есть только один результат (или вы только хотите, чтобы окончательная добавленная линия добавлена ), достаточно просто удалить конечный характер выхода, который вы можете сделать по трубе через головы -C-1
.
X
– zetah 03.03.2012, 03:23CR
, но будетLF
. Мне было нелегко понимать то, что Вы хотите от вопроса, надо надеяться, мое редактирование делает то, что Вы хотите. – Chris Down 03.03.2012, 03:27grep/sed
решение вместо этогоawk
(который я не понимаю), и если не я буду использовать его. Спасибо – zetah 03.03.2012, 03:40