Замена текстовых строк в bash с помощью awk - PullRequest
0 голосов
/ 01 ноября 2019

У меня есть список файлов в bash - file1.txt , file2.txt , file3.txt , и я хотел бы сделать еще один список, которыйвключить эти строки без .txt , поэтому

names2 = (file1, file2, file3)

Затем я хотел бы найти эти строки в файле и добавить перед ними эти строки. Как это сделать, пожалуйста?

Мой код:

names = (file1.txt, file2.txt, file3.txt)

for i in "${names[@]}"; do
    awk '{ gsub("$i","a-$i") }' f.txt > g.txt

f.txt:

TEXT
\connect{file1}
\begin{file2}
\connect{file3}
TEXT 
75

Желаемый вывод g. TXT

TEXT
\connect{a-file1}
\begin{a-file2}
\connect{a-file3}
TEXT 
75

Ответы [ 2 ]

2 голосов
/ 01 ноября 2019

С sed + printf:

$ names=(file1 file2 file3) # Declare array

$ printf 's/%s/a-&/g\n' "${names[@]}" # Generate sed replacement script
s/file1/a-&/g
s/file2/a-&/g
s/file3/a-&/g

$ sed -f <(printf 's/%s/a-&/g\n' "${names[@]}") f.txt
TEXT
\connect{a-file1}
\begin{a-file2}
\connect{a-file3}
TEXT
75

Если ваш массив содержит суффикс .txt, используйте это:

$ names=(file1.txt file2.txt file3.txt) # Declare array

$ printf 's/%s/a-&/g\n' "${names[@]%.txt}" # Generate sed replacement script
s/file1/a-&/g
s/file2/a-&/g
s/file3/a-&/g

$ sed -f <(printf 's/%s/a-&/g\n' "${names[@]%.txt}") f.txt
TEXT
\connect{a-file1}
\begin{a-file2}
\connect{a-file3}
TEXT
75

Если список files содержит имена, которые перекрываютсястрока, вы можете использовать границы слова (\<, \>) для обработки этого. например,

$ cat f.txt
TEXT
\connect{file1}
\begin{file2}
\connect{file3file2}
TEXT 
75

$ names=(file1.txt file2.txt file3file2.txt) # Declare array
$ printf 's/\<%s\>/a-&/g\n' "${names[@]%.txt}" # Generate sed replacement script
s/\<file1\>/a-&/g
s/\<file2\>/a-&/g
s/\<file3file2\>/a-&/g

$ sed -f <(printf 's/\<%s\>/a-&/g\n' "${names[@]%.txt}") f.txt
TEXT
\connect{a-file1}
\begin{a-file2}
\connect{a-file3file2}
TEXT 
75
2 голосов
/ 01 ноября 2019

Не могли бы вы попробовать следующее.

Переменная со значениями в оболочке:

string="file1.txt, file2.txt, file3.txt"

Создание массива оболочки следующим образом:

IFS=', ' read -r -a array <<< "$string"

ИЛИ, если хотитепридерживаясь способа определения массива, выполните следующие действия:

array=(file1.txt file2.txt file3.txt)

Передача созданного выше оболочки массива в awk и чтение Input_file для выполнения заключительных операций.

awk -v arr="${array[*]}" '
BEGIN{
  FS=OFS="{"
  num=split(arr,array," ")
  for(i=1;i<=num;i++){
    sub(/\.txt/,"",array[i])
    array1[array[i]"}"]
  }
}
$2 in array1{
  $2="a-"$2
}
1
'  Input_file

Объяснение: Добавление объяснения приведенного выше кода здесь.

awk -v arr="${array[*]}" '       ##Creating a variable named arr whose value is all elements of array(shell array).
BEGIN{                           ##Starting BEGIN section of awk code here.
  FS=OFS="{"                     ##Setting FS and OFS as { here.
  num=split(arr,array," ")       ##Splitting arr variable into array named array with delimiter space and its length is stored in num variable.
  for(i=1;i<=num;i++){           ##Starting for loop from i=1 to till value of variable num.
    sub(/\.txt/,"",array[i])     ##Using sub to substitute .txt with NULL in array value whose index is variable named i.
    array1[array[i]"}"]          ##Creating an array1 whose index is array[i] value with } in it.
  }                              ##Closing for loop here.
}                                ##Closing BEGIN section of code here.
$2 in array1{                    ##Checking condition if $2 of current line is present in array named array1 then do following.
  $2="a-"$2                      ##Adding string a- with value of $2.
}                                ##Closing BLOCK for condition here.
1                                ##Mentioning 1 will print edited/non-edited line of Input_file.
'  Input_file                    ##Mentioning Input_file name here.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...