Преобразование нескольких строк в одну строку с пробелами и кавычками

Действия

rmпри работе с несколькими файлами или каталогами не являются атомарными. В данном случае это имеет значение, потому что rm -rвыполняет поиск файлов и каталогов снизу вверх -, удаляя их из листьев в корень запрошенного пути. Это делается с помощью unlinkи rmdirдо тех пор, пока ничего не останется, а затем rmdirявляется конечным каталогом.

Эти действия происходят последовательно, поэтому, если до выдачи rmdirсоздается больше файлов, вы получаете ответENOTEMPTY("Каталог не пуст" ).

Более чем вероятно, что ваш скрипт или другой процесс, работающий в системе, создает вещи одновременно с rm -rf.Возможно, вам следует подумать о:

  1. Делать это синхронно, а не асинхронно или
  2. Повторите попытку rm -rf, если она не удалась и возвращает ENOTEMPTY (, хотя тогда другое приложение может завершиться ошибкой, поскольку каталог был удален из-под него)

Вы можете найти другое приложение, которое создает файлы, используя что-то вроде fanotifyили скрипт eBPF, например opensnoopиз BCC . inotifyтакже может быть полезным, но, к сожалению, он не включает процесс создания файлов в свои выходные данные.

Другая возможность заключается в том, что удаление файла не удалось, но это может быть замаскировано -f. Попробуйте запустить без -f, чтобы увидеть, что может быть ошибкой в ​​этом случае.

6
24.06.2020, 14:32
10 ответов

Сsed + paste

$ sed 's/.*/"&"/' databases.txt
"Wp_new"
"Frontend DB"
"DB_EXT"

$ sed 's/.*/"&"/' databases.txt | paste -sd' ' -
"Wp_new" "Frontend DB" "DB_EXT"

Или простоpaste(вежливостьhttps://unix.stackexchange.com/a/593240)

$ <databases.txt paste -d '"' /dev/null - /dev/null | paste -sd' ' -
"Wp_new" "Frontend DB" "DB_EXT"


Если ввод содержит пустые строки, их следует игнорировать:

$ cat ip.txt
Wp_new

Frontend DB



DB_EXT
$ sed -n 's/..*/"&"/p' ip.txt | paste -sd' ' -
"Wp_new" "Frontend DB" "DB_EXT"
7
18.03.2021, 23:26

Это можно сделать с помощью

awk '{printf("\"%s\" ",$0)} END { printf "\n" }' databases.txt

Выход:

"Wp_new" "Frontend DB" "DB_EXT" 
12
18.03.2021, 23:26

чтобы ваш вывод был текстовым файлом POSIX:

awk '
function output(sep, record){ printf "\"%s\"%s", record, sep } 
prev{ output(FS, prev) } { prev=$0 } END{ output(ORS, prev) }' infile
2
18.03.2021, 23:26
$ awk '{printf "%s\"%s\"", sep, $0; sep=OFS} END{print ""}' file
"Wp_new" "Frontend DB" "DB_EXT"
3
18.03.2021, 23:26

Существует несколько способов достижения результата с помощью sed. Вот два решения:

$ sed 's/^/"/;s/$/"/' infile | sed ':a;{N;s/\n/ /;ba}'
"Wp_new" "Frontend DB" "DB_EXT"

или

$ sed 's/.*/"&"/' infile | sed ':a;{N;s/\n/ /;ba}'
"Wp_new" "Frontend DB" "DB_EXT"

Сначала в начало и конец каждой текстовой строки добавляются двойные кавычки, затем текстовые строки объединяются.

2
18.03.2021, 23:26

Вот еще одно sedрешение. Неизбежно, он имеет некоторое совпадение с ответами fpmurphy и Sundeep .

{ sed 's/.*/"&"/; 1!s/^/ /' databases.txt | tr -d '\n'; echo;}
  • Заключить каждую строку в кавычки.
  • Добавьте пробелв началокаждой строки, кроме первой.
  • Удалить все новые строки.
  • Добавить новую строку в конце.

Как отмечает Сандип, вы можете переместить < databases.txtв начало команды если вы особенно предпочитаете видеть спецификацию ввода в этой позиции (, а не в середине команды ). И вы можете заменить echoна printf '\n'— хотя, следуя комментариям Эда Мортона , echoмогли бы лучше генерировать соответствующие конец -символа строки -(s )в чем-то другом, кроме чистого контекста Unix/Linux (например, гибрид Windows/GNU ).

1
18.03.2021, 23:26

Мне нравится использовать tr(1)для преобразования многострочных строк в однострочные, а затем работать с ними с помощью sed(1), сначала вставляя конечную и начальную кавычки, а затем заменяя все «внутренние» точки с запятой, т.е.:

$ cat databases.txt | tr '\n' ';' | sed 's/;$/"\n/; s/^/"/; s/;/" "/g'
"Wp_new" "Frontend DB" "DB_EXT"

Конечно, вы можете выбрать любой другой символ, кроме ;, если он не содержится в самом вводе.

Хотя об этом должно быть легко рассуждать, это не обязательно переносимо и определенно не POSIX, как правильно указал @g -man -говорит -восстановить -monica. Проблема заключается в том, что sed необходимо прочитать всю строку ---здесь весь файл ---, в то время как POSIX требует только 8192-байтовых строк(1). Кроме того, ввод для sed должен быть файлом (, т.е. заканчиваться новой строкой 2).

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

1
18.03.2021, 23:26

Это можно сделать в некотором sed с помощью:

$ sed ':a;N;$!ba;s/\n/" "/g;s/.*/"&"/' databases.txt 

"Wp_new" "Frontend DB" "" "DB_EXT" "" "empty"

Или, если вам не нравятся названия веток и веток:

$ sed -n '/^$/!{                                          
    ${H;x;s/\n/" "/g;s/.*/"&"/;p;d;}
    $!{H;1h}
    }' databases.txt 

"Wp_new" "Frontend DB" "DB_EXT" "empty"

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

С некоторой помощью пасты sed мог читать строки один -в -в -раз:

$ sed 's/.*/"&"/' databases.txt | paste -sd ' '

"Wp_new" "Frontend DB" "" "DB_EXT" "" "empty"

Нет необходимости в обычном ' -' для вставки, так как он по умолчанию читается со стандартного ввода, если не указан ФАЙЛ.

Это также можно сделать в awk с явными значениями:

$ awk 'BEGIN{dq="\""; sp=""} {
     printf "%s%s%s%s", sp, dq, $0,dq; sp=" "
     }END{print ""}' databases.txt 

"Wp_new" "Frontend DB" "DB_EXT"
2
18.03.2021, 23:26

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

Просто свернуть текст:

cat yourFile | paste -sd' ' -
>item1 item2 item3

Элемент объемного звучания с двойными -кавычками:

sed -n 's/..*/"&",/p' yourFile | paste -sd' ' -
>"item1", "item2", "item2",
0
21.09.2021, 14:56
awk 'ORS=" "{print "\""$0"\""}' filename

выход

"Wp_new" "Frontend DB" "DB_EXT"
1
21.09.2021, 19:03

Теги

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