ෂෙල් ස්ක්‍රිප්ටයේ නූල් හැසිරවීම භාවිතා කරමින් නූලක අවසාන අක්‍ෂරය මකන්න


210

නූලක අවසාන අක්‍ෂරය මකා දැමීමට මම කැමතියි, මම මෙම කුඩා පිටපත උත්සාහ කළෙමි:

#! /bin/sh 

t="lkj"
t=${t:-2}
echo $t

නමුත් එය "lkj" මුද්‍රණය කරයි, මම කරන්නේ කුමක්ද?

Answers:


124

POSIX කවචයක, සින්ටැක්ස් ${t:-2}යන්නෙන් අදහස් කරන්නේ වෙනස් දෙයක් - එය සකසා tතිබේ tනම් සහ ශුන්‍ය නොවන්නේ නම් අගයට සහ වෙනත් ආකාරයකින් වටිනාකමට පුළුල් 2වේ. පරාමිති ප්‍රසාරණය අනුව තනි අක්‍ෂරයක් කැපීමට, ඔබට බොහෝ විට අවශ්‍ය වන වාක්‍ය ඛණ්ඩය වේ${t%?}

එම සටහන ksh93, bashහෝ zsh, ${t:(-2)}හෝ ${t: -2}(සටහන් අවකාශය) වේ එය substring පුළුල් ලෙස නීතිමය නමුත් ඔවුන් අවසානයේ සිට අක්ෂර 2 තත්වයක දී ආරම්භ substring නැවත පටන්, ඔබට අවශ්ය දේ නොවේ බොහෝ විට (එනම් එය ඉවත් පළමු චරිතය iපිළිබඳ string ijk).

වැඩි විස්තර සඳහා බෑෂ් යොමු අත්පොතේ ෂෙල් පරාමිති පුළුල් කිරීමේ කොටස බලන්න:


4
'%' පිටුපස ඇති මායාව කුමක්දැයි පැහැදිලි කිරීමට ඔබ කැමතිද? ?
afraisse

9
rafraisse ${parameter%word}කෙටිම උපසර්ග රටා ගැලපීම ඉවත් කරයිwordman bash
වානේ ධාවකයේ

3
මෙය Bash 4.1.2 සඳහා හොඳින් ක්‍රියා කරයි: CentOS / RHEL 6.x
T

214

සමග bash4.2 සහ ඊට ඉහළ, ඔබට කළ හැකි දේ:

${var::-1}

උදාහරණයක්:

$ a=123
$ echo "${a::-1}"
12

පැරණි සඳහා bash(උදාහරණයක් ලෙස, bash 3.2.5OS X හි), ඔබ කොලොන් අතර සහ පසු අවකාශයන් තැබිය යුතු බව සලකන්න:

${var: : -1}

13
මෙය bash4.2-ඇල්ෆා සහ ඊට ඉහළ අනුවාදය සඳහා ක්‍රියා කරයි , මට ප්‍රවේශ වීමට ඇති අනුවාදය මීට පෙර නරක ය. : - /
hjk

2
@iamaziz: bash changelog වෙතින්, in ණ දිග ${var:offset:lenght}එකතු කරන ලද්දේ ඇතුළත පමණි bash 4.2. සමහර විට OSX සඳහා තමන්ගේම පැච් එකක් එකතු කරයි bash.
cuonglm

1
@cuonglm වැඩ කරන්නේ නැත: /
iamaziz

2
මැක් මත ක්‍රියා නොකරයි.
ෂින්සෝ

1
MACsters, රුස්ගේ පිළිතුර දෙස බලන්න
P i

71

හෝ nභාවිතා නොකරන පේළියකින් අවසාන අක්ෂර ඉවත් කිරීම සඳහා :sedawk

> echo lkj | rev | cut -c (n+1)- | rev

උදාහරණයක් ලෙස ඔබට one characterමෙය භාවිතා කර අවසාන අක්‍ෂරය මකා දැමිය හැකිය :

> echo lkj | rev | cut -c 2- | rev

> lk

revmanpage වෙතින් :

විස්තරය
පුනරාවර්තන උපයෝගීතාව මඟින් නිශ්චිත ලිපිගොනු සම්මත නිමැවුමට පිටපත් කර සෑම පේළියකම අක්ෂර අනුපිළිවෙල වෙනස් කරයි. ලිපිගොනු කිසිවක් නිශ්චිතව දක්වා නොමැති නම්, සම්මත ආදානය කියවනු ලැබේ.

යාවත්කාලීන කිරීම:

ඔබ නූල් වල දිග නොදන්නේ නම්, උත්සාහ කරන්න:

$ x="lkj"
$ echo "${x%?}"
lk

70

Sed භාවිතා කිරීම එය තරම් වේගවත් විය යුතුය

sed 's/.$//'

ඔබේ තනි දෝංකාරය එවිට echo ljk | sed 's/.$//'වේ.
මෙය භාවිතා කරමින්, 1-පේළියේ නූල ඕනෑම ප්‍රමාණයක් විය හැකිය.


12
පොදු අවස්ථාවක, එය නොවන බව සටහන වැල අවසන් අක්ෂරය මකා , නමුත් අවසන් අක්ෂරය වැල සෑම මාර්ගය .
ස්ටෙෆාන් චසෙලාස්

50

කවචය මත පදනම්ව විකල්ප කිහිපයක්:

  • පොසික්ස්: t=${t%?}
  • බෝර්න්: t=`expr " $t" : ' \(.*\).'`
  • zsh / yash: t=${t[1,-2]}
  • bash / zsh: t=${t:0:-1}
  • ksh93 / bash / zsh / mksh: t=${t:0:${#t}-1}
  • ksh93 / bash / zsh / mksh: t=${t/%?}
  • ksh93: t=${t/~(E).$/}
  • es: @ {t=$1} ~~ $t *?

සියල්ලන්ම අන්තිම අක්‍ෂරය ඉවත් කළ යුතු යැයි සිතන අතර , සමහර ක්‍රියාත්මක කිරීම් (බහු-බයිට් අක්ෂර සඳහා සහය නොදක්වන) අන්තිම බයිට් එක වෙනුවට ඉවත් කරන බව ඔබට පෙනී යනු ඇත (එබැවින් එය අවසාන බහුවිධ බයිට් නම් දූෂිත වනු ඇත. ).

මෙම exprප්රභේද්යයක් උපකල්පනය $tඑකකට වඩා වැඩි පේලීයක් දී අවසන් නොවේ. එහි ප්‍රති string ලයක් ලෙස ඇති වන නූල අවසන් වුවහොත් 0(හෝ සමහර ක්‍රියාත්මක කිරීම් සමඟ 000වුවද -0) එය ශුන්‍ය නොවන පිටවීමේ තත්වයක් ලබා දෙනු ඇත. නූලෙහි වලංගු නොවන අක්ෂර තිබේ නම් එය අනපේක්ෂිත ප්‍රති results ල ලබා දිය හැකිය.


ලස්සන හා ගැඹුරු! නමුත් ... මම හිතන්නේ ඒ ෂෙල් වෙඩි සියල්ලම POSIX සඳහා සහය දක්වයි, එබැවින් සෑම කෙනෙකුම එය භාවිතා කළ යුත්තේ වඩාත්ම අතේ ගෙන යා හැකි ය. කුඩාම අක්ෂර ගණනද!
රුස්

Us රුස්, t=${t%?}බෝර්න් නොවේ, නමුත් මේ දිනවල ඔබට බෝර්න් කවචයක් හමු නොවනු ඇත. ${t%?}අනෙක් සියල්ලටම වැඩ කරයි.
ස්ටෙෆාන් චසෙලාස්

මාළු ෂෙල් විකල්පයක් ලබා දී නැත! Ksh93 ට වඩා මේ දිනවල බොහෝ ජනප්‍රියයි ...
rien333

@ rien333. අතුරු මුහුණත ටිකක් ස්ථාවර වන තෙක් මම බලා සිටිමි. fishවැඩ කරමින් පවතී. 2.3.0 බිල්ඩින් හඳුන්වා දුන් අතර stringඑය ප්‍රශ්නෝත්තර අවස්ථාවේදී නිකුත් නොවීය. මම එය පරික්‍ෂා කරන අනුවාදය සමඟ, ඔබට අවශ්‍යය string replace -r '(?s).\z' '' -- $t(තවද ඔවුන් එය වෙනස් කිරීමට කැමති යැයි මම බලාපොරොත්තු වෙමි, ඔවුන් PCRE වෙත යවන ධජ වෙනස් කළ යුතුය) හෝ වැඩි කැටි කළ ඒවා. එය නව රේඛා අක්ෂර සමඟ ද දුර්වල ලෙස ගනුදෙනු කරන අතර, ඔවුන් ද එය වෙනස් කිරීමට සැලසුම් කර ඇති බව මම දනිමි.
ස්ටෙෆාන් චසෙලාස්

POSIX පිළිතුර සඳහා ඉහළට. Bash 3.2.57 (1) හි වැඩ කිරීම තහවුරු කර ඇත
අවීන්ද්‍ර ගූල්චරන්

37

වඩාත්ම අතේ ගෙන යා හැකි හා කෙටිම පිළිතුර නිසැකවම පාහේ ය:

${t%?}

මෙය bash, sh, ash, dash, busybox / ash, zsh, ksh, ආදියෙහි ක්‍රියා කරයි.

එය ක්‍රියාත්මක වන්නේ පැරණි පාසල් ෂෙල් පරාමිති ප්‍රසාරණය භාවිතා කිරීමෙනි. නිශ්චිතවම, ගෝලීය රටාවට %ගැලපෙන පරාමිතියේ කුඩාම ගැලපෙන උපසර්ගය ඉවත් කිරීමට නියම tකරයි ?(එනම්: ඕනෑම අක්ෂරයක්).

"ලොව කුඩාම ෙයදුම රටාව ඉවත් කරන්න" බලන්න මෙතන අ (බොහෝ) වඩාත් සවිස්තරාත්මක පැහැදිලි කිරීමක් හා වඩා පසුබිම. man bash"පරාමිති ප්‍රසාරණය" යටතේ ඔබේ කවචය සඳහා (උදා:) ලියකියවිලි බලන්න .


පැති සටහනක් ලෙස, ඔබට ඒ වෙනුවට පළමු අක්‍ෂරය ඉවත් කිරීමට අවශ්‍ය නම් , ඔබ භාවිතා කරනුයේ ${t#?}, #පිටුපස (උපසර්ගය) වෙනුවට නූල් ඉදිරිපසින් (උපසර්ගය) ගැලපෙන බැවිනි .

එසේම සඳහන් කිරීම වටී, දෙකම %සහ #ඇති %%සහ ##අනුවාදයන්, කෙටිම වෙනුවට ලබා දී ඇති රටාවේ දීර් version තම අනුවාදයට ගැලපේ . මේ අවස්ථාවේ දී දෙකම ${t%%?}සහ ${t##?}ඔවුන්ගේ තනි ක්‍රියාකරු මෙන් ම කරනු ඇත (එබැවින් නිෂ් less ල අමතර අක්ෂර එකතු නොකරන්න). මෙයට හේතුව ලබා දී ඇති ?රටාව එක් අක්ෂරයකට පමණක් ගැලපෙන බැවිනි . දී මිශ්ර *නොවන සමහර-ආදේශක හා දේවල් සමග වඩා රසවත් වෙන්න සමග %%හා ##.

පරාමිති පුළුල් කිරීම් අවබෝධ කර ගැනීම හෝ අවම වශයෙන් ඒවායේ පැවැත්ම ගැන දැන ගැනීම සහ ඒවා දෙස බලන ආකාරය දැන ගැනීම බොහෝ රසයන්ගේ ෂෙල් පිටපත් ලිවීමට හා තේරුම් ගැනීමට ඇදහිය නොහැකි තරම් ප්‍රයෝජනවත් වේ. පරාමිති ප්‍රසාරණය බොහෝ විට බොහෝ දෙනෙකුට ආකේන් ෂෙල් වෝඩූ මෙන් පෙනේ ... මන්ද ... ඒවා ආකේන් ෂෙල් වෝඩූ (ඔබ "පරාමිති ප්‍රසාරණය" සෙවීමට දන්නේ නම් එය මනාව ලේඛනගත කර ඇත). ඔබ කවචයක සිරවී සිටින විට මෙවලම් පටිය තුළ සිටීම ඇත්තෙන්ම හොඳයි.


1
කෙටි හා පැණිරස, මැකෝස් සහ ලිනක්ස් යන දෙවර්ගයේම ක්‍රියා කරයි!
dbernard

18
t=lkj
echo ${t:0:${#t}-1}

ඔබට 0 සිට නූල් දිග -1 දක්වා උපස්ථරයක් ලැබේ. කෙසේ වෙතත් මෙම උපස්ථරය බාෂ් විශේෂිත වන අතර අනෙක් ෂෙල් වෙඩි මත ක්‍රියා නොකරනු ඇත.

උදාහරණයක් ලෙස, dashවිග්‍රහ කිරීමට පවා නොහැකිය

echo ${t:0:$(expr ${#t} - 1)}

උදාහරණයක් ලෙස, උබුන්ටු හි, /bin/shවේdash


15

headඅවසාන අක්‍ෂරය හැර අනෙක් සියල්ල මුද්‍රණය කිරීමටද ඔබට භාවිතා කළ හැකිය .

$ s='i am a string'
$ news=$(echo -n $s | head -c -1)
$ echo $news
i am a strin

නමුත් අවාසනාවකට සමහර අනුවාදවල headප්‍රමුඛ -විකල්පය ඇතුළත් නොවේ. මේ සඳහා නඩුව headමෙහෙයුම් පද්ධතිය සමඟ එන බව X.


6

නිත්‍ය ප්‍රකාශනය භාවිතා කිරීම පහසුය:

n=2
echo "lkj" | sed "s/\(.*\).\{$n\}/\1/"

6

සමහර පිරිපහදු. අක්ෂර එකකට වඩා ඉවත් කිරීමට, ඔබට ප්‍රශ්න ලකුණු කිහිපයක් එකතු කළ හැකිය. උදාහරණයක් ලෙස, විචල්‍යයෙන් අවසාන අක්ෂර දෙක ඉවත් කිරීමට:, $SRC_IP_MSGඔබට මෙය භාවිතා කළ හැකිය:

SRC_IP_MSG=${SRC_IP_MSG%??}

4

පිරිසිදු බාෂ් භාවිත කළ හැකි භාවිතයන් කිහිපයක් සම්පූර්ණ කිරීම සඳහා:

#!/bin/bash

# Testing substring removal
STR="Exemple string with trailing whitespace "
echo "'$STR'"
echo "Removed trailing whitespace: '${STR:0:${#STR}-1}'"
echo "Removed trailing whitespace: '${STR/%\ /}'"

පළමු වාක්‍ය ඛණ්ඩය නූලකින් උපස්ථරයක් ගනී, සින්ටැක්ස් යනු දෙවැන්න සඳහා, ලකුණ සැලකිල්ලට ගන්න, එහි තේරුම 'රේඛාවේ කෙළවරේ සිට' සහ සින්ටැක්ස් ය
${STRING:OFFSET:LENGTH}
%
${STRING/PATTERN/SUBSTITUTION}

ඉහත සඳහන් කළ කෙටි ආකාර දෙකක් මෙහි දැක්වේ

echo "Removed trailing whitespace: '${STR::-1}'"
echo "Removed trailing whitespace: '${STR%\ }'"

මෙහි ඇති සං %sign ාව නැවත අවධානය යොමු කරන්න, එහි අර්ථය 'ඉවත් කරන්න (එනම්,' වෙනුවට ආදේශ කරන්න) කෙටිම ගැලපෙන රටාව (මෙහි පරාමිතියේ අවසානයේ සිට පැන ගිය අවකාශය '\' නිරූපණය කරයි - මෙහි STR ලෙස නම් කර ඇත.


1

අපට php විධාන රේඛාවේ හෝ ෂෙල් ස්ක්‍රිප්ට් භාවිතා කළ හැකිය . සමහර විට එය ශල්‍ය විග්‍රහ කිරීම සඳහා ප්‍රයෝජනවත් වේ.

php -r "echo substr('Hello', 0, -1);" 
// Output hell

පයිප්ප සමඟ:

echo "hello" | php -r "echo substr(trim(fgets(STDIN)), 0, -1);"
// Output hell

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.