इनपुट:
1
hgh
h2b
h4h
2
ok
koko
lkopk
3
uh
ju
nfjvn
4
अपेक्षित उत्पादन:
1
2
3
4
इसलिए, मुझे आउटपुट फ़ाइल में फ़ाइल का केवल 1, 5 वां, 9 वां, 13 वां मान होना चाहिए। यह कैसे करना है?
इनपुट:
1
hgh
h2b
h4h
2
ok
koko
lkopk
3
uh
ju
nfjvn
4
अपेक्षित उत्पादन:
1
2
3
4
इसलिए, मुझे आउटपुट फ़ाइल में फ़ाइल का केवल 1, 5 वां, 9 वां, 13 वां मान होना चाहिए। यह कैसे करना है?
जवाबों:
AWK का उपयोग करना:
awk '!((NR - 1) % 4)' input > output
यह पता लगाना कि पाठक के लिए यह एक अभ्यास के रूप में कैसे छोड़ा जाता है।
NR % 4 == 1अधिक सुपाठ्य IMO होगा।
का उपयोग कर split (GNU coreutils):
split -nr/1/4 input > output
-nCHUNKSआउटपुट फ़ाइलें उत्पन्न करेंऔर के CHUNKSरूप में
r/K/N राउंड रॉबिन वितरण और केवल आउटपुट K का उपयोग करें N का बंटवारा लाइनों / रिकॉर्ड के बिना stdout करने के लिएGNU के साथ sed:
sed '1~4!d' < input > output
मानक के साथ sed:
sed -n 'p;n;n;n' < input > output
साथ 1और 4में $nऔर $iचर:
sed "$n~$i!d" # GNU only
awk -v n="$n" -v i="$i" 'NR >= n && (NR % i) == (n % i)'
पायथन संस्करण, सिर्फ मनोरंजन के लिए:
with open('input.txt') as f:
for i, line in enumerate(f.readlines()):
if i%4 == 0:
print(line.strip())
enumerate(f)कम मेमोरी का उपभोग करते हुए काम करने में सक्षम होना चाहिए
readlines(इसलिए पूरी फ़ाइल को मेमोरी में खिसकाते हैं), तो आप f.readlines()[::4]हर चौथी पंक्ति को प्राप्त करने के लिए उपयोग कर सकते हैं । तो आप उपयोग कर सकते हैं print(''.join(f.readlines()[::4]))।
POSIX sed: यह विधि पॉज़िक्ली सीड का उपयोग करती है और इसलिए इसे हर जगह चलाया जा सकता है, या पॉज़िक का सम्मान करने वाले उन सेड्स को कम से कम चलाया जा सकता है।
$ sed -ne '
/\n/!{
H;s/.*//;x
}
:loop
$bdone
N;s/\n/&/4
tdone
bloop
:done
s/.//;P
' input.file
एक और स्केलेबिलिटी उद्देश्यों के लिए प्रोग्रामेटिक सेड कोड जनरेशन है:
$ code=$(yes n | head -n 4 | paste -sd\; | sed s/n/p/)
$ sed -ne "$code" input.file
Perl: हम सरणी A को तब तक भरते हैं जब तक उसका आकार 4 न हो। फिर हम इसके पहले तत्व को प्रिंट करते हैं और साथ ही एरे को भी साफ करते हैं।
$ perl -pe '
$A[@A] = @A ? <> : $_ while @A < 4;
$_ = (splice @A)[0];
' input.file
scriptname filename skip(अपने मामले में 4) के साथ कॉल करें। यह iterफ़ाइल के शीर्ष से लाइनें खींचकर काम करता है और फिर केवल अंतिम आउटपुट देता है। यह तब तक वृद्धि करता iterहै skipsऔर तब तक दोहराता है जब तक कि मूल्य iterउस linesसे अधिक न हो जाए file।
#!/bin/bash
file="$1"
lines=`wc -l < "$file"`
skips="$2" || "4"
iter=1
while [ "$iter" -le "$lines" ]; do
head "$file" -n $iter | tail -n 1
iter=$(( $iter + $skips ))
done
शुद्ध बैश:
mapfile -t lines < input
for (( i=0; i < ${#lines[@]}; i+=4 ))
do printf "%s\n" "${lines[$i]}"
done
मेपफाइल बैश 4 में जोड़ा गया एक बिलियन है जो मानक इनपुट को एक सरणी में पढ़ता है, यहां नाम दिया गया है lines, जिसमें एक प्रविष्टि प्रति पंक्ति है। -tविकल्प अंतिम नई-पंक्तियों स्ट्रिप्स।
यदि आप लाइन 4 से शुरू होने वाली हर चौथी लाइन को प्रिंट करना चाहते हैं, तो आप कर सकते हैं कि एक कमांड में mapfileकॉलबैक ऑप्शन का उपयोग करके -C, जो दिए गए कोड को इतनी सारी लाइनों को चलाता है, जिसके द्वारा दिए गए अंतराल के साथ -c। वर्तमान सरणी सूचकांक और सौंपी जाने वाली अगली पंक्ति को तर्क के रूप में कोड को दिया जाता है।
mapfile -t -c4 -C 'printf "%.0s%s\n"' < input
यह printfबिलिन का उपयोग करता है ; प्रारूप कोड %.0sपहले तर्क (इंडेक्स) को दबा देता है, इसलिए केवल रेखा मुद्रित होती है।
आप पंक्ति 1, 2, या 3 से शुरू होने वाली प्रत्येक चौथी पंक्ति को प्रिंट करने के लिए एक ही कमांड का उपयोग कर सकते हैं, लेकिन आपको इसे फीड करने से पहले 3, 2, या 1 लाइनों को inputपूर्व-निर्धारित करना होगा mapfile, जो मुझे लगता है कि इसके लायक होने से अधिक परेशानी है ।
यह भी काम करता है:
mapfile -t lines < input
printf "%s%.0s%.0s%.0s\n" "${lines[@]}"
यहां, एक बार में printfचार प्रविष्टियों की खपत होती है lines, केवल पहले को प्रिंट करना और अन्य तीन को छोड़ देना %.0s। मुझे यह पसंद नहीं है क्योंकि आपको अलग-अलग अंतराल या शुरुआती बिंदुओं के लिए प्रारूप स्ट्रिंग के साथ मैन्युअल रूप से फ़ेड करना है।
sed -n '1~4p'