Я ищу скрипт bash. В текстовом файле у меня есть такие данные:
+------+------
| Id | User |
+------+------+
| 8192 | root |
| 8194 | root |
| 8202 | root |
| 8245 | root |
| 8434 | root |
| 8754 | root |
| 8761 | root |
| 8762 | root |
| 8764 | root |
| 8771 | root |
+------+------+
Я хочу извлечь данные следующим образом:
8192,8194,8202,8245,8434,8754,8761, 8762,8764
Я имею в виду, мне нужно первое поле, содержащее числа, но не последнее. И все извлеченные числа должны быть разделены запятой (,
).
Может ли кто-нибудь помочь мне получить это?
Вам не нужен сценарий для такой простой вещи. Можно использовать awk
:
awk '$2 ~ "^[0-9][0-9]*$" { print $2 }' file.txt | head -n -1 | awk '{print}' ORS=',' | sed 's/,$/\n/'
Некоторые объяснения:
awk '$2 ~ "^[0-9][0-9]*$" { print $2 }' file.txt
- печатают от file.txt
только поля, которые являются числами. head -n -1
- удаляют последнюю строку / последнее число. awk '{print}' ORS=','
- связывают все строки в одной одной строке, каждое число, разделенное ,
. sed 's/,$/\n/'
- заменяют в последний раз ,
символом новой строки. Или, короче:
awk '$2 ~ "^[0-9][0-9]*$" { print $2 }' ORS=',' file.txt | sed 's/,[0-9]*,$/\n/'
Самым самым коротким путем я могу найти:
echo `sed 's/[^0-9]//g' your_file` | sed 's/ /,/g'
Результат:
8192,8194,8202,8245,8434,8754,8761,8762,8764,8771
[^0-9]
- означает, что все кроме numericals
s/[^0-9]//g
- удаляет все кроме Замены numericals
your_file
с путем к Вашему файлу
Для Вас наконец задача, с kill
команда. Быть тщательно при использовании этой строки, это уничтожит каждый PID в списке :
for pid in `sed 's/[^0-9]//g' your_file | grep -v '^ Перед выполненной предыдущей строкой, можно хотеть выполнить эту строку:
for pid in `sed 's/[^0-9]//g' your_file | grep -v '^ Это покажет что-то вроде этого:
kill -9 8192
kill -9 8194
kill -9 8202
kill -9 8245
kill -9 8434
kill -9 8754
kill -9 8761
kill -9 8762
kill -9 8764
kill -9 8771
<час> Удачи!
`; do echo "kill -9 $pid";done
Это покажет что-то вроде этого:
kill -9 8192
kill -9 8194
kill -9 8202
kill -9 8245
kill -9 8434
kill -9 8754
kill -9 8761
kill -9 8762
kill -9 8764
kill -9 8771
<час> Удачи!
`; do kill -9 $pid;done
Перед выполненной предыдущей строкой, можно хотеть выполнить эту строку:
for pid in `sed 's/[^0-9]//g' your_file | grep -v '^ Это покажет что-то вроде этого:
kill -9 8192
kill -9 8194
kill -9 8202
kill -9 8245
kill -9 8434
kill -9 8754
kill -9 8761
kill -9 8762
kill -9 8764
kill -9 8771
<час> Удачи!
`; do echo "kill -9 $pid";done
Это покажет что-то вроде этого:
kill -9 8192
kill -9 8194
kill -9 8202
kill -9 8245
kill -9 8434
kill -9 8754
kill -9 8761
kill -9 8762
kill -9 8764
kill -9 8771
<час> Удачи!
Вот один лайнер для Вашей цели,
sed 's/[^0-9]//g' file.txt| xargs | sed 's/ /,/g'
или
sed 's/[+|IdUserroot\-]*//g' file.txt | xargs | sed 's/ /,/g'
Вывод:
8192,8194,8202,8245,8434,8754,8761,8762,8764,8771
Объяснение
man sed
s/regexp/replacement/
Attempt to match regexp against the pattern space. If successful, replace that
portion matched with replacement. The replacement may contain the special charac‐
ter & to refer to that portion of the pattern space which matched, and the special
escapes \1 through \9 to refer to the corresponding matching sub-expressions in the
regexp.
g Copy/append hold space to pattern space.
Регулярное выражение <глоток> [Википедия] глоток>
[^ ] Matches a single character that is not contained within the brackets.
For example, [^abc] matches any character other than "a", "b", or "c". [^0-9]
matches any single character that is not a number from "0" to "9".
Следовательно использование sed
я заменил все пространством. Затем xargs
помещает их в строку, разделенную пространством,
$ sed 's/[^0-9]//g' file.txt| xargs
8192 8194 8202 8245 8434 8754 8761 8762 8764 8771
Наконец шаг, я заменил все пробелы ,
использование sed
где текст находится в input
файл в том же каталоге, и результат дан в output
файл.
cat ./input | sed -e 's/+------+------+//g' | sed -e 's/| Id | User |//g' | sed -e 's/ | root |//g' | tr -d "\n" | sed -e 's/| /,/g' | sed -e 's/ ,/,/g' | sed -e 's/ ,/,/g' > output
, Когда я сделал это Ваш пример, я добрался:
+------+------,8192,8194,8202,8245,8434,8754,8761,8762,8764,8771
, Который может, потому что верхняя строка Вашего примера отсутствовала +
- может быть несколько других ошибок...
Тогда я думаю, что просто необходимо добавить sudo /mysql_rms/bin/mysqladmin -S /mysql_rms/var/mysql_rms.sock -p kill
вначале
Или, в том, что является, надо надеяться, небольшим улучшением на какой предложенный Radu (также на основе вышеупомянутого входа):
cat ./input | sed 's/[+-]*//g' | sed 's/ | root |//g' | tr -d "\n" | sed 's/| /,/g' | sed 's/ ,/,/g' | sed 's/ ,/,/g' | sed 's/^,//' | sed 's/,[0-9]* $/\n/' | sed 's/Id//g' | sed 's/,User,,//g' | sed 's/ //g' > output
Затем на основе Вас Q& здесь , необходимо быть в состоянии работать:
sudo /mysql_rms/bin/mysqladmin -S /mysql_rms/var/mysql_rms.sock -p kill $(cat ./output)
, хотя можно хотеть проверить, является ли это правильной командой с этим сначала:
echo "sudo /mysql_rms/bin/mysqladmin -S /mysql_rms/var/mysql_rms.sock -p kill $(cat ./output)"
Я думаю, что это - то, в чем Вы нуждались. Некоторым другим ответам не удалось удалить последнюю часть.
sed -n 's/.*\([0-9]\{4\}\).*/\1/p' file | sed ':a;N;$!ba;s/\n/,/g; s/\(.*\),\(.*\)$/\1/g'
А небольшой пример,
$ (echo '| Id | User |'; echo '| 8192 | root |'; echo '| 8194 | root |'; echo '| 8771 | root |') | sed -n 's+.*\([0-9]\{4\}\).*+\1+p' | sed ':a;N;$!ba;s/\n/,/g; s/\(.*\),\(.*\)$/\1/g'
8192,8194