Удалять строки между двумя шаблонами, но только если между ними есть определенная строка

Самый простой способ сгенерировать файл, понятный Microsoft Excel, - это использовать формат CSV, поскольку это просто текст в простом формате. В стандартном формате строки разделяются новой строкой, ячейки разделяются запятыми, при этом двойные кавычки используются для заключения в кавычки полей, содержащих проблемные символы, такие как запятая и новая строка, а сам двойной символ вводится как "" .

Одна вещь, которую не определяет формат файла CSV, - это набор символов, используемый в тексте файла. Об этом нужно сообщать другими способами.

Переменное содержимое в виде одной ячейки

Чтобы вывести строку CSV с этими 3 переменными, все, что нам нужно сделать, это:

  • экранировать символы " внутри переменных
  • заключить это в двойные кавычки
  • соединяются с запятыми
  • добавляют символ новой строки.

Встроенная функция printf оболочки ksh93 как % # q ] для вывода строки в виде поля CSV, поэтому позаботится о первых двух пунктах выше для тех значений, которые необходимо заключить в кавычки. Таким образом, в этой оболочке это просто:

 printf '%#q,%#q,%#q\n' "$var1" "$var2" "$var3"

С bash / zsh / ksh , вы можете выполнить эту кодировку вручную и заключить каждую ячейку в кавычки:

 printf '"%s","%s","%s"\n' "${var1//\"/\"\"}" "${var2//\"/\"\"}" "${var3//\"/\"\"}"

POSIXly, вы можете использовать awk для кодирования:

awk '
  BEGIN {
    for(i = 1; i < ARGC; i++) {
      gsub(/"/, "\"\"", ARGV[i])
      printf "%s\"%s\"", sep, ARGV[i]
      sep = ","
    }
    printf "\n"
  }' "$var1" "$var2" "$var3" > file.csv

На вашем вводе все они дают:

"'file:'""$AI_SERIAL_LOOKUP""'/GDFS_Off_Peak_Lkp.txt'
'file:'""$AI_SERIAL_LOOKUP""'/mssu2_massched.mssulrm_lkup_'""$AI_PHASE""'.txt'
'file:'""${AI_SERIAL_TEMP}""","$PRIVATE_SCRIPT/2_ctc_rpt_dds_extn_stage_load.ksh ${AI_SERIAL}/${AB_JOB}_dds_parm_extn_iri_ctc_rpt.dat _${DestType} ${CURR_TIME_STAMP}
$PRIVATE_SCRIPT/1_ctc_rpt_dds_extn_stage_to_base.ksh ${AI_SERIAL}/${AB_JOB}_ ${DestType} ${CURR_TIME_STAMP}","TGDM01.T3113_DA_DLVR_SP a,
TGIDM01.T3121_RT_REQ_CHK b
TGIM01.T3121_RPT_RQ_CHK"

Каждая строка каждой переменной как ячейка электронной таблицы

Это становится более сложным, поскольку вам также необходимо разделить переменные на ее строки.

С ksh93 и его форматом % # q :

IFS=
while
  found=false
  read -ru3 a && found=true
  read -ru4 b && found=true
  read -ru5 c || "$found"
do
  printf '%#q,%#q,%#q\n' "$a" "$b" "$c"
done 3<<< "$var1" 4<<< "$var2" 5<<< "$var3" > file.csv

С bash / zsh / ksh ], вы также можете использовать paste для вставки 3 потоков, состоящих из раскрытия переменных, в которых экранировано ":

paste -d '"",' - <(printf '%s\n' "${var1//\"/\"\"}") - \
               - <(printf '%s\n' "${var2//\"/\"\"}") - \
               - <(printf '%s\n' "${var3//\"/\"\"}") - < /dev/null > file.csv

, что на вашем вводе даст:

"'file:'""$AI_SERIAL_LOOKUP""'/GDFS_Off_Peak_Lkp.txt'","$PRIVATE_SCRIPT/2_ctc_rpt_dds_extn_stage_load.ksh ${AI_SERIAL}/${AB_JOB}_dds_parm_extn_iri_ctc_rpt.dat _${DestType} ${CURR_TIME_STAMP}","TGDM01.T3113_DA_DLVR_SP a,"
"'file:'""$AI_SERIAL_LOOKUP""'/mssu2_massched.mssulrm_lkup_'""$AI_PHASE""'.txt'","$PRIVATE_SCRIPT/1_ctc_rpt_dds_extn_stage_to_base.ksh ${AI_SERIAL}/${AB_JOB}_ ${DestType} ${CURR_TIME_STAMP}","TGIDM01.T3121_RT_REQ_CHK b"
"'file:'""${AI_SERIAL_TEMP}""","","TGIM01.T3121_RPT_RQ_CHK"

2
28.09.2016, 17:49
2 ответа
sed '/^[[:blank:]]*"crosshair"/,/}/{H;/}/!d;s/.*//;x;/sprites\/crosshairs/d;s/.//;}' infile

Как это работает:

sed '/^[[:blank:]]*"crosshair"/,/}/{         # in this range
H                                            # append each line to hold buffer
/}/!d                                        # delete it if not the end of range
s/.*//                                       # empty the pattern space
x                                            # exchanges buffers
/sprites\/crosshairs/d                       # delete pattern space if it matches
s/.//                                        # remove leading newline, autoprint
}' infile

Предполагается, что строки совпадают с ^ [[: blank:]] * всегда следует "перекрестие" блоком строк, заключенным в фигурные скобки, как в вашем примере.

2
27.01.2020, 22:04

если perl в порядке, можно использовать режим абзаца (параметр -00 ) и использовать многострочный соответствие регулярному выражению

$ cat ip.txt 
eggs
bacon
cereal

eggs
bacon
cheese
cereal

$ perl -00 -ne 'print if !/^eggs.*cheese.*cereal$/ms' ip.txt 
eggs
bacon
cereal
1
27.01.2020, 22:04

Теги

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