УДАР:Удалить символ новой строки из строки (прочитанная строка)

StackOverflow https://stackoverflow.com/questions/1459250

  •  12-09-2019
  •  | 
  •  

Вопрос

Я столкнулся со следующей проблемой:Я пишу скрипт Linux bash, который выполняет следующее:

  • Прочитать строку из файла
  • Разденьте \n символ из конца строки просто прочитайте
  • Выполните команду, которая находится там

Пример:commands.txt

ls
ls -l
ls -ltra
ps as

Выполнение файла bash должно получить первую строку и выполнить ее, но в то время как \n в настоящее время оболочка просто выводит "команда не найдена:ls" Эта часть сценария выглядит следующим образом

 read line

        if [ -n "$line" ]; then #if not empty line

                #myline=`echo -n $line | tr -d '\n'`
                #myline=`echo -e $line | sed ':start /^.*$/N;s/\n//g; t start'`

                myline=`echo -n $line | tr -d "\n"`
                $myline  #execute it

                cat $fname | tail -n+2 > $fname.txt
                mv $fname.txt $fname
        fi

Прокомментировал, что у вас есть то, что я пробовал, прежде чем спросить об этом.Есть какие-нибудь решения?Последние пару часов я ломаю себе голову над этим...

Это было полезно?

Решение

Мне всегда нравится perl -ne 'chomp and print' , для обрезки новых строк.Приятный и легко запоминающийся.

например , ls -l | perl -ne 'chomp and print'

Однако

Хотя я не думаю, что это ваша проблема здесь.Хотя я не уверен, что понимаю, как вы передаете команды из файла на "чтение" в вашем сценарии оболочки.

С помощью моего собственного тестового сценария, подобного этому (test.sh)

read line
if [ -n "$line" ]; then
  $line
fi

и пример входного файла, подобного этому (test.cmds)

ls 
ls -l
ls -ltra

Если я запущу это следующим образом ./test.sh < test.cmds, Я вижу ожидаемый результат, который заключается в выполнении первой команды 'ls' в текущем рабочем каталоге.

Возможно, в вашем входном файле есть дополнительные непечатаемые символы ?

мой выглядит вот так

od -c test.cmds 
0000000    l   s      \n   l   s       -   l  \n   l   s       -   l   t
0000020    r   a  \n                                                    
0000023

Из ваших комментариев ниже я подозреваю, что у вас могут быть возвраты каретки (" ") в вашем входном файле, что не то же самое, что перевод строки.Является ли входной файл изначально в формате DOS ?Если это так, то вам нужно преобразовать 2-байтовую строку DOS, заканчивающуюся " ", в однобайтовую UNIX-строку " " для достижения ожидаемых результатов.

Вы должны быть в состоянии сделать это, заменив " " на " " в любой из ваших закомментированных строк.

Другие советы

Кто-то уже написал программу, которая выполняет команды оболочки:файл sh

Если вы действительно хотите выполнить только первую строку файла: head -n 1 file |sh

Если ваша проблема заключается в возврате каретки: tr -d '\r' <file |sh

Я попробовал это:

read line
echo -n $line | od -x

Для ввода 'xxxx' я получаю:

0000000 7878 7878

Как вы можете видеть, здесь нет \n в конце содержимого переменной.Я предлагаю запустить скрипт с опцией -x (bash -x script).При этом будут выводиться все команды по мере их выполнения.

[РЕДАКТИРОВАТЬ] Ваша проблема в том, что вы отредактировали commands.txt в Windows.Теперь файл содержит CRLF (0d0a) в качестве разделителей строк, что сбивает с толку readls\r не является известной командой).Использование dos2unix или аналогично, чтобы превратить его в файл Unix.

Вы также можете попытаться заменить возврат каретки переводом строк только с помощью встроенных Bash:

line=$'a line\r' 
line="${line//$'\r'/$'\n'}" 
#line="${line/%$'\r'/$'\n'}"       # replace only at line end
printf "%s" "$line" | ruby -0777 -n -e 'p $_.to_s' 

вам нужна команда eval


#!/bin/bash -x

while read  cmd
do
 if [ "$cmd" ]
 then
  eval "$cmd"
 fi
done

Я запустил его как
./script.sh < file.txt

И file.txt был:

ls
ls -l
ls -ltra
ps as

хотя и не работает на ls, Я рекомендую взглянуть на find’s -print0 вариант

Следующий скрипт работает (по крайней мере, для меня):

#!/bin/bash

while read I ; do if [ "$I" ] ; then $I ; fi ; done ;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top