Улучшение программы sed - условия - PullRequest
0 голосов
/ 02 ноября 2019

Я использую этот код в соответствии с этим вопросом .

$ 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

Как сделать условия, которые решают следующую проблему, пожалуйста?

names=(file1.txt file2.txt file3file2.txt) 

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

Я пытался

sed -f <(printf 's/{%s}/{s-&}/g\n' "${files[@]%.tex}")

, но в результате получается

\input{a-{file1}}

Мне нужно найти {% s} и a-место между {и% s

Ответы [ 2 ]

1 голос
/ 02 ноября 2019

Поскольку это объяснение слишком длинное для комментария, добавьте ответ здесь. Я не уверен, был ли мой предыдущий ответ ясным или нет, но мой ответ позаботится об этом случае и заменит только только точные имена файлов, а НЕ смесь имен файлов.

Допустим, ниже приведены значения массива и Input_file:

names=(file1.txt file2.txt file3file2.txt)
echo "${names[*]}"
file1.txt file2.txt file3file2.txt

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

Теперь, когда мы запустим следующий код:

awk -v arr="${names[*]}" '
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
' file1

Вывод будет следующим. Вы могли видеть, что file3 НЕ заменен, так как он НЕ присутствовал в значении массива.

TEXT
\connect{a-file1}
\begin{a-file2}
\connect{file3}
TEXT
75
1 голос
/ 02 ноября 2019

Непонятно из вопроса, как разрешить конфликтующие данные. В частности, код заменит любой экземпляр file1 на a-file1, даже такие вещи, как 'foofile1'.

На первый взгляд, цель состоит в том, чтобы изменить токены (например, на foofile1 не должно влиятьПодстановка file1. Этого можно достичь, добавив утверждение границы слова (\ b) - до и после имени файла. Это предотвратит совпадение шаблона внутри других более длинных имен файлов.

printf 's/\\b%s\\b/a-&/g\n' "${names[@]%.txt}"
...