2016-01-07 18 views
6

Mam plik tekstowy, w którym chcę zamienić ciąg z nowym ciągiem, a następnie dodać lub usunąć spacje, aby uzyskać taką samą liczbę znaków. Na przykład, chcę wymienićsed - zamień ciąg znaków na równą liczbę znaków

string    .10 

z

longer_string  .10 

w istocie muszę wymienić „string”, a następnie mieć”.10' w odpowiedniej kolumnie, regarldess liczby znaki w ciągu zastępującym.

+0

Hi @ ericvb86 masz na myśli coś takiego jak ten "sed-e"/string/longer_string/g 'file.txt'? –

+0

możesz użyć zamiennika skryptu ed lub vim, aby to zrobić, w przeciwnym razie możesz utworzyć skrypt, który jest niezależny od rozmiaru łańcucha dopasowania rozmiaru zastępczego, aby dopasować/zastąpić potrzebne spacje, niezależnie od rozmiaru diff. – alexscott

+0

Re alexscott's odpowiedź: tak, miałem zamiar powiedzieć, że to wygląda bardziej na pracę dla vi/vim niż sed. Wyszukaj ciąg ('/^string'), vim-replace z dłuższym ciągiem znaków (' Rlonger-string '). Nie znam dokładnego kodu vimscript dla tego; musisz zbadać: https://en.wikipedia.org/wiki/Vim_(text_editor)#Vim_script. –

Odpowiedz

1

Można użyć sed, aby wykonać wymianę, a następnie ewentualnie ponownie wyrównać kolumny za pomocą column?

cat input.txt | sed 's/string/longer_string/g' | column -t 
+1

Uwaga: "plik kota | sed' ma UUoC. Lepszy plik "sed" .... – fedorqui

+0

Co jest z UFLA?Osobiście lubię przykłady ilustrujące przepływ od lewej do prawej :) –

+0

Nie jestem pewien co to jest UFLA: D UUoC to http://porkmail.org/era/unix/award.html:) – fedorqui

1

Możesz wydrukować wiersz i dołączyć powrót karetki; Następnie należy wydrukować nową linię:

while IFS= read -r line; 
do 
    echo -ne "$line\r" 
    echo -ne "longer_string" 
done < file 

Więc w pliku byłoby:

$ while IFS= read -r line; do echo -ne "$line\r"; echo -ne "longer_string"; done < file 
longer_string  .10 

Uwaga Działa to dobrze, jeśli ciąg wymiana jest dłuższy od oryginału. W przeciwnym razie możemy potrzebować dodatkowych kroków.

0

Sed to niewłaściwe narzędzie do pracy tutaj.

czego potrzebujesz to:

  1. rozdzielić słowa do pracy ("string" &”.10") i przechowywać je w zmiennych
  2. Znajdź długość skrajnej lewej komponentu
  3. Modyfikuj "string"
  4. wydrukować zmodyfikowane ciągi w stałych kolumn szerokości

tu idzie:

# 1 
str="string    .10" 
a=$(echo "$str" | awk '{print $1}') 
b=$(echo "$str" | awk '{print $2}') 

# 2 
# note the use of `echo -n` to avoid n+1 errors with `wc`. It does not change anything here because we're subtracting anyway, but if you play around it might bite you. 
str_length=$(echo -n "$str" | wc -c) 
b_length=$(echo -n "$b" | wc -c) 
leftmost_length=$(($str_length - $b_length)) 

# 3 
a="longer_${a}" 

# 4 
printf "%-${leftmost_length}s %-10s\n" "$a" "$b" 
# longer_string  .10 
0

To może pracować dla Ciebie (GNU sed):

sed -r 's/string(.*)/\nlonger_string\1\n&/;ta;:a;s/\n(\S)(.*\n)./\1\n\2/;ta;s/\n.*\n(.*)/\1/' file 

Zastępuje string z longer_string a następnie dołącza oryginalną linię do zaktualizowanego jednego (nowe linie są poprzedzany do starych i nowych ciągów) . Następnie znaki są usuwane z dołączonej linii do momentu dopasowania końca nowego ciągu. Spacje (minus wprowadzony znak nowej linii) ze starej linii zastępują pozostałą część zmodyfikowanej linii.

Powiązane problemy