Могу я спросить, как понять следующий скрипт bash?

#bash #sed

#bash #sed

Вопрос:

Могу я спросить, что пытается сделать следующий скрипт bash?

 args=$(echo $@ |sed "s/^ *//;s/ *$//;s/ {1,}/ /g;s/-{1,} /-/g;s/ -/t-/g")
  

Спасибо!

Ответ №1:

Давайте разберем его:

  1. s/^ *//;
  2. s/ *$//;
  3. s/ {1,}/ /g;
  4. s/-{1,} /-/g;
  5. s/ -/t-/g

    1. Удаляет пробелы в начале строки

    2. Удаляет пробелы в конце строки

    3. Заменяет пробелы одним пробелом

    4. Заменяет тире единственным тире

    5. Заменяет пробел и тире табуляцией и прочерком

Ответ №2:

Скрипт обрезает аргументы, переданные сценарию через командную строку. (Массив всех аргументов может быть адресован с помощью $@ в командной строке)

Обрезка означает, что она удаляет избыточные пробелы в середине строк и полностью удаляет пробелы в начале и конце каждого аргумента. В дальнейшем ваш код заменит пробел перед дефисом на TAB .

Преобразования, выполняемые командой, подробно:

 s/^ *//          --> remove 0 or more spaces at the start of the string
s/ *$//          --> remove 0 or more spaces at the end of the string
/ {1,}/ /g     --> "melts" multiple spaces into one
s/-{1,} /-/g   --> Removes one or more white space after the hypen `-`
s/ -/t-/g       --> Removes a space in front of a hypen by a TAB
  

Ответ №3:

Давайте разделим его на небольшие фрагменты, чтобы было легче понять:

  1. Удалите все пробелы в начале строки

     s/^ *//;
      
  2. Удалите все пробелы в конце строки

     s/ *$//;
      
  3. Замените два или более пробела одним пробелом

     s/ {1,}/ /g;
      
  4. Замените два или более тире, за которыми следует пробел - , одним тире

     s/-{1,} /-/g;
      
  5. Замените пробел и тире - на табуляцию и прочерк t-

     s/ -/t-/g
      

Комментарии:

1. @AvinashRaj Ну, {1,} означает «один или несколько пробелов», но поскольку это заменяется одним пробелом, это эффективно означает «Заменить два или более пробела одним пробелом».

Ответ №4:

sed очищает пробелы и изменяет это:

 sdfgsdfg
  afadsfads fadsf
adsfadf   adfadfads
adfadfa - adsfdsf
dfadsf - dsfds
dfsd   -   sdfsd
  

К этому:

 sed "s/^ *//;s/ *$//;s/ {1,}/ /g;s/-{1,} /-/g;s/ -/t-/g" file
sdfgsdfg
afadsfads fadsf
adsfadf adfadfads
adfadfa -adsfdsf
dfadsf  -dsfds
dfsd    -sdfsd
  

Вы можете сделать это проще, используя awk

 awk '{$1=$1;sub(/ - /,"t-")}1' file
sdfgsdfg
afadsfads fadsf
adsfadf adfadfads
adfadfa -adsfdsf
dfadsf  -dsfds
dfsd    -sdfsd
  

Или в вашем случае:

 args=$(echo $@ | awk '{$1=$1;sub(/ - /,"t-")}1')