I есть такие строки в файле
x;x;x;x;x;x;cmd="lbk_addcolumn TABLE_NAME_1 COLUMN_X";x;x;x;x
x;x;x;x;x;x;cmd="lbk_dropcolumn TABLE_NAME_2 COLUMN_Y";x;x;x;x
Я хочу заменить поле с "cmd" в файле на что-то вроде этого:
x;x;x;x;x;x;cmd="ColumnAdded TABLE_NAME_1 COLUMN_X || lbk_addcolumn TABLE_NAME_1 COLUMN_X";x;x;x;x
x;x;x;x;x;x;cmd="ColumnDropped TABLE_NAME_2 COLUMN_Y || lbk_dropcolumn TABLE_NAME_2 COLUMN_Y ";x;x;x;x
Как я могу это сделать?
Вы можете попробовать следующий сценарий Bash:
while read ln; do
out=`sed 's/\([^"]*\)"\([^"]*\)\(.*\)/\1"\2 || \2\3/' <<< "$ln"`
out=`sed -e 's/lbk_addcolumn/ColumnAdded/' -e 's/lbk_dropcolumn/ColumnDropped/' <<< "$out"`
echo "$out"
done < input.txt
где input.txt
содержит ваши строки
sed -r -e "s/(lbk_addcolumn.*)(\[.*\])\s*(\[.*\])/ColumnAdded \2 \3 || \1 \2 \3/g" \
-e "s/(lbk_dropcolumn.*)(\[.*\])\s*(\[.*\])/ColumnDropped \2 \3 || \1 \2 \3/g" input.txt
где input. txt
- это ваш контент
Вместо уродливых шаблонов sed regex, Если все строки имеют одинаковый фиксированный формат, как ваши две строки (6*x;cmd="...";4*x), нижеприведенные альтернативные команды выполняют работу в файле, не требуя цикла чтения файла.
Ключевым моментом (если формат устойчив во всех строках) является использование "
в качестве разделителя, разрезая строки на 3 отдельных поля.
$ sed 's/lbk_addcolumn/ColumnAdd/;s/lbk_dropcolumn/ColumnDrop/' <(awk -F'"' '{if (($0=="")) print $0;else print $1"\""$2" || "$2"\""$3}' file.txt)
Или :
$ a=$(awk -F'"' '{if (($0=="")) print $0;else print $1"\""$2" || "$2"\""$3}' file.txt)
$ sed 's/lbk_addcolumn/ColumnAdd/;s/lbk_dropcolumn/ColumnDrop/' <<<"$a"
awk разбивает каждую строку файла с "
в качестве разделителя.
если $0=""
, то это пустая строка, печатаем пустую строку и идем дальше
else выведите все поля строки в требуемом порядке.
Наконец, sed заменяет первый найденный текст lbk_addcolumn
на ColumnAdd
.
Тест:
$ cat e.txt
x;x;x;x;x;x;cmd="lbk_addcolumn TABLE_NAME_1 COLUMN_X";x;x;x;x
x;x;x;x;x;x;cmd="lbk_dropcolumn TABLE_NAME_2 COLUMN_Y";x;x;x;x
# sed 's/lbk_addcolumn/ColumnAdd/;s/lbk_dropcolumn/ColumnDrop/' <(awk -F'"' '{if (($0=="")) print $0;else print $1"\""$2" || "$2"\""$3}' e.txt)
x;x;x;x;x;x;cmd="ColumnAdd TABLE_NAME_1 COLUMN_X || lbk_addcolumn TABLE_NAME_1 COLUMN_X";x;x;x;x
x;x;x;x;x;x;cmd="ColumnDrop TABLE_NAME_2 COLUMN_Y || lbk_dropcolumn TABLE_NAME_2 COLUMN_Y";x;x;x;x
Того же результата можно добиться даже только с помощью awk и использования функции gsub awk:
$ awk -F'"' '{if ($0=="") print $0;else {a=$2;gsub("lbk_addcolumn","ColumnAdd",$2);gsub("lbk_dropcolumn","ColumnDrop",$2);print $1"\""$2" || "a"\""$3;}}' e.txt
x;x;x;x;x;x;cmd="ColumnAdd TABLE_NAME_1 COLUMN_X || lbk_addcolumn TABLE_NAME_1 COLUMN_X";x;x;x;x
x;x;x;x;x;x;cmd="ColumnDrop TABLE_NAME_2 COLUMN_Y || lbk_dropcolumn TABLE_NAME_2 COLUMN_Y";x;x;x;x
awk лучше представляет:
$ awk -F'"' '{
if ($0=="") print $0;
else {
a=$2;
gsub("lbk_addcolumn","ColumnAdd",$2);
gsub("lbk_dropcolumn","ColumnDrop",$2);
print $1"\""$2" || "a"\""$3;
}
}' e.txt