Як я можу зняти перші символи X із рядка за допомогою sed?


126

Я пишу сценарій оболонки для вбудованого Linux у невеликий промисловий ящик. У мене є змінна, що містить текст, pid: 1234і я хочу позбавити перших символів X з рядка, тому залишається лише 1234. У мене є більше змінних, які мені потрібно "очистити", тому мені потрібно відрізати X перших символів і ${string:5}чомусь не працює в моїй системі.

Єдине, що, мабуть, є у коробці sed.

Я намагаюся зробити так, щоб працювати:

result=$(echo "$pid" | sed 's/^.\{4\}//g')

Будь-які ідеї?


10
Якщо ${string:5}це не працює, ви не використовуєте Bash або іншу оболонку, яка підтримує цей синтаксис. Яку оболонку та версію ви використовуєте? Як виглядає твій шебанг? Я здогадуюсь, що ви використовуєте sh(наприклад, dash) або можливо zsh.
Призупинено до подальшого повідомлення.

Відповіді:


0

Це також зробить роботу:

echo "$pid"|awk '{print $2}'

27
Це питання є першим зверненням до "пропустити перші N символів у рядку". Ви не відповіли на запитання.
jww

Це, здається, не працює, і якщо це так, ви можете пояснити, як
Олександр Міллз

Це працює в моїй системі. Можливо, проблема з роздільником поля, спробуйте awk -F": " '{print $2}'. Все-таки не моє улюблене рішення.
mzuther

197

Слід працювати:

var="pid: 1234"
var=${var:5}

Ви впевнені bash, що оболонка виконує ваш сценарій?

Навіть сумісні з POSIX

var=${var#?????}

було б кращим, ніж використання зовнішнього процесу, хоча це вимагає жорсткого кодування 5 у вигляді шаблону фіксованої довжини.


1
Ви також можете вказати довжину за допомогою другого параметра: ${var:5:2}почнеться з 1та повернеться 12.
Макс Кандокія

108

Ось стислий спосіб вирізати перші X символи за допомогою cut(1). Цей приклад видаляє перші 4 символи, вирізавши підрядку, починаючи з 5-го символу.

echo "$pid" | cut -c 5-

2
Це найпростіше рішення!
Брендон

2
Технічно ОП попросив sed, але я вважаю, що це найкраще рішення для "Як я можу зняти перші символи X із рядка [в терміналі / bash]" При використанні в поєднанні з git, це добре:git log --pretty=oneline | cut -c 42- | head
marksiemers

1
+1 Просте і корисне рішення .. Коли я мав URL як http: // <example.com> і скорочував протокол 'http: //', я повинен сказати як 8 символів замість 7. Я не знаю , але саме так у мене це вийшло.
Сантош Кумар Арджунан

1
Сантош Кумар Арджунан: це тому, що приклад "ехо" $ pid "| cut -c 4-" насправді не вирізає перші 4 символи, а витягує підрядку, починаючи з 4-го символу. Тому він фактично скорочує перші 3 символи. Таким чином, якщо ви хочете вирізати 7 перших символів, ви хочете витягти все з 8-го символу і, таким чином, зробити "cut -c 8-"
al-ash

1
@DeanHiller cut -c ${LEN}-. Фігурні дужки використовуються для об'єднання рядка з дійсними символами змінної, щоб розрізнити, що є змінною, а що ні. Якщо ви хочете отримати додаткову інформацію про це, то знайдіть "конфіскацію рядкових змінних рядків" для отримання додаткових ресурсів щодо того, чому / як це працює.
JustCarty

46

Використовуйте -rпараметр ("використовувати розширені регулярні вирази в сценарії") для sed, щоб використовувати {n}синтаксис:

$ echo 'pid: 1234'| sed -r 's/^.{5}//'
1234

1
як би це було у випадку, якщо я хотів би зняти останні символи X із рядка?
Кокеш

5
@Kokesh: sed -r 's/.{5}$//'замість цього можна зняти останні 5 символів
Марк Лонгейр

7
Ви можете зробити це без -r( -Eв OS X, IIRC), якщо уникнути дужок (не знаю, чи це працює в OS X, хоча).
Призупинено до подальшого повідомлення.

2
@Dennis: Я щойно перевірив - уникнення брекетів (і відключення -r/ -E) працює в ОС X.
Гордон Девіссон

15

Виріжте перші два символи з рядка:

$ string="1234567890"; echo "${string:2}"
34567890

@ dtp70 Дякую велику загальну відповідь, це спрацювало чудово!
wolfram77

10

передайте його awk '{print substr($0,42)}'туди, куди 42 - це більше, ніж кількість символів, які потрібно скинути. Наприклад:

$ echo abcde| awk '{print substr($0,2)}'
bcde
$

8

Швидше за все, і у вас буде cut. Якщо так:

[me@home]$ echo "pid: 1234" | cut -d" " -f2
1234

1
Проблема cutполягає в тому, що він не обробляє послідовності пробілів розумно, використання tr -s ' '"стискання" пробілів змушує себе вести себе краще.
Тор

1
Це не означає бути інструментом, що співає всі танці; це просто і робить, як говориться на банці, і широко доступний. Він повинен спрацьовувати добре для зазначених вимог, і, безумовно, більш надійний, ніж обрізання фіксованих символів з певних позицій.
Шон Чін

5

Ну, там були рішення тут з sed, awk, cutі з допомогою bashсинтаксису. Я просто хочу передати інший варіант, відповідний POSIX:

$ echo "pid: 1234" | tail -c +6
1234

-cповідомляє хвіст, з якого байтового зміщення розпочати, рахуючи з кінця вхідних даних, але якщо число починається зі +знаку, воно знаходиться від початку вхідних даних до кінця.


4

Інший спосіб, використовуючи cutзамість sed.

result=`echo $pid | cut -c 5-`

Він хоче видалити перші 4 символи. При цьому виходять перші 4 символи.
ММ.

2

Я знайшов відповідь у чистому стилі, наданому цим питанням (правда, опублікований після розміщення цього запитання). Це робить саме те, що ви просили, виключно в sed:

result=\`echo "$pid" | sed '/./ { s/pid:\ //g; }'\``

Точка в sed '/./) - це все, що ви хочете відповідати. Ваше запитання - саме те, що я намагався, за винятком мого випадку, я хотів зіставити певний рядок у файлі та скасувати його. У моєму випадку це було:

# Uncomment a line (edit the file in-place):
sed -i '/#\ COMMENTED_LINE_TO_MATCH/ { s/#\ //g; }' /path/to/target/file

-iПісля того, як sedце відредагувати файл на місці (видалити цей перемикач , якщо ви хочете , щоб перевірити ваше вираз відповідності до редагування файлу).

(Я опублікував це, тому що хотів це зробити цілком за допомогою sed, оскільки це питання задав, і жоден з попередніх відповідей не вирішив цю проблему.)


1

Замість того, щоб видаляти n символів із самого початку, можливо, ви могли просто витягнути цифри безпосередньо. Як так ...

$ echo "pid: 1234" | grep -Po "\d+"

Це може бути більш надійним рішенням і здається більш інтуїтивним.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.