Измените текст на однострочном числе в нескольких текстовых файлах

Вы на правильном пути. Если ssh сессия является оболочкой входа в систему (вместо удаленной команды), bash получит /etc/bash.logout и ~/.bash_logout когда Вы выходите из оболочки.

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

bash -l -c /execute/some/command

От man 1 bash

-c string   If  the  -c  option  is  present, then commands are read from 
string.  If there are arguments after the string, they are assigned to 
the positional parameters,  starting with $0.
-l   Make bash act as if it had been invoked as a login shell 

When  a login shell exits, bash reads and executes commands from the 
files ~/.bash_logout and /etc/bash.bash_logout, if the files exists.
4
13.04.2017, 15:37
3 ответа
for file in f1 f2; do
  sed -i '8s/^.*$/foo/' "$file"
done
5
27.01.2020, 20:49
  • 1
    Почему не просто sed -i '8s/^.*$/foo/' f1 f2? –  l0b0 22.06.2013, 00:51
  • 2
    @l0b0 Вы попробовали это? –  Hauke Laging 22.06.2013, 00:59
  • 3
    Работавший отлично: echo test1 > f1; echo test2 > f2; sed -i '1s/^.*$/foo/' f1 f2. cat f1 f2 шоу, на которые оба были изменены foo. –  l0b0 22.06.2013, 01:05
  • 4
    @l0b0 Это забавно. Я попробовал это сначала, но без -i. И в этом случае всего одна строка была изменена. Не имеет смысла мне. Ошибка (sed-версия 4.2.1 GNU)? –  Hauke Laging 22.06.2013, 01:10
  • 5
    Попробуйте -s: "рассмотрите файлы как отдельные, а не как единственный непрерывный длинный поток". –  l0b0 22.06.2013, 11:28

Используя awk

for file in script1.sh script2.sh script3.sh ... script10.sh; do
    temp=$(mktemp)
    awk '
        BEGIN {
            line8 = "This is line 8"
            line21["script1.sh"] = "XYZ"
            line21["script2.sh"] = "PQR"
            line21["script3.sh"] = "ABC"
            # ... 
        }
        FNR == 8 { print line8; next }
        FNR == 21 && FILENAME in line21 { print line21[FILENAME]; next }
        {print}
    '  "$file" > "$temp" && mv "$temp" "$file"
done

или, с помощью удара и sed

# bash variables to store new values. requires bash v4 for the associative array
line8="This is line 8"
declare -A line21=(
    [script1.sh]="XYZ"
    [script2.sh]="PQR"
    [script3.sh]="ABC"
    # ...
)
# then use sed
for file in script1.sh script2.sh script3.sh ... script10.sh; do
    sed -i "8s/.*/$line8/; 21s/.*/${line21[$file]}/" "$file"
done

С sed решением необходимо быть осторожными, который новые строки не содержат "/" символы, поскольку это повредится s/// команда. Хотя можно использовать различные символы-разделители, такой как s|pattern|replacement| (в этом случае то же предупреждение применяется, рекурсивно),

ed работы также:

for file in script1.sh script2.sh script3.sh ... script10.sh; do
    ed "$file" <<ED_COMMANDS
8d
8i
$line8
.
21d
21i
${line21[$file]}
.
w
q
ED_COMMANDS
done
2
27.01.2020, 20:49

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

Вопрос 1

  1. Perl:

    for f in *.sh; do 
      perl -i -lne '$.==8 ? print "This is line 8" : print;' "$f"; 
    done
    
  2. awk и варианты:

    for f in *.sh; do 
      awk '{if(NR==8){print "This is line 8"}else{print}}' "$f" > fifo && 
      mv fifo "$f";
    done
    

Вопрос 2

Я сначала создал бы файл с заменами, которые я хочу сделать. Например:

script1.sh  foo1
script2.sh  foo2
script3.sh  foo3
script4.sh  foo4

Затем считайте тот файл для выполнения замен:

while read f s; do 
 export s;
 perl -i -lne '$.==8 ? print "$ENV{s}" : print;' "$f";
done < sublist.txt
2
27.01.2020, 20:49

Теги

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