क्या यह संभव है बदलने के मूल्य के एक सेल में एक csv फ़ाइल का उपयोग कर grep,sed या दोनों

0

सवाल

मैं लिखा है, निम्न आदेश

#!/bin/bash
awk -v value=$newvalue -v row=$rownum -v col=1 'BEGIN{FS=OFS=","} NR==row {$col=value}1' "${file}".csv >> temp.csv && mv temp.csv "${file}".csv

नमूना इनपुट फ़ाइल है । सीएसवी

Header,1
Field1,Field2,Field3
1,ABC,4567
2,XYZ,7890

Assuiming $newvalue=3 ,$rownum=4 और col=1, तो उपरोक्त कोड से बदलें:

अपेक्षित उत्पादन

Header,1
Field1,Field2,Field3
1,ABC,4567
3,XYZ,7890

तो अगर मैं पता है कि पंक्ति और स्तंभ में, यह संभव है को प्रतिस्थापित करने के लिए कहा मूल्य का उपयोग कर grep, sed?

Edit1: Field3 हमेशा के लिए एक अद्वितीय मान उनके संबंधित पंक्तियों. ( मामले में है कि जानकारी में मदद करता है वैसे भी)

bash csv git-bash linux
2021-11-24 06:52:47
3

सबसे अच्छा जवाब

1

यह मानते हुए अपनी CSV फाइल के रूप में सरल है क्या आप को दिखाने के लिए (कोई अल्पविराम में उद्धृत क्षेत्रों), और अपने newvalue शामिल नहीं करता है कि पात्रों sed व्याख्या करेंगे एक खास तरीके से (उदाहरण के लिए एम्परसेंड्स, स्लैश या backslashes), निम्नलिखित के साथ काम करना चाहिए बस sed (परीक्षण के साथ जीएनयू एसईडी):

sed -Ei "$rownum s/[^,]*/$newvalue/$col" file.csv

डेमो:

$ cat file.csv
Header,1
Field1,Field2,Field3
1,ABC,4567
3,XYZ,7890
$ rownum=3
$ col=2
$ newvalue="NEW"
$ sed -Ei "$rownum s/[^,]*/$newvalue/$col" file.csv
$ cat file.csv
Header,1
Field1,Field2,Field3
1,NEW,4567
3,XYZ,7890

स्पष्टीकरण: $rownum प्रयोग किया जाता है के रूप में पते (यहाँ लाइन नंबर) जहां लागू करने के लिए निम्न आदेश. s है, sed विकल्प कमान. [^,]* नियमित रूप से अभिव्यक्ति के लिए खोज और की जगह: सबसे लंबे समय तक संभव स्ट्रिंग युक्त नहीं एक अल्पविराम. $newvalue प्रतिस्थापन है । $col घटना की जगह के लिए.

अगर newvalue हो सकता है एम्परसेंड्स, स्लैश या backslashes हम चाहिए sanitize यह पहली बार:

sanitizednewvalue=$(sed -E 's/([/\&])/\\\1/g' <<< "$newvalue")
sed -Ei "$rownum s/[^,]*/$sanitizednewvalue/$col" file.csv

डेमो:

$ newvalue='NEW&\/&NEW'
$ sanitizednewvalue=$(sed -E 's/([/\&])/\\\1/g' <<< "$newvalue")
$ echo "$sanitizednewvalue"
NEW\&\\\/\&NEW
$ sed -Ei "$rownum s/[^,]*/$sanitizednewvalue/$col" file.csv
$ cat file.csv
Header,1
Field1,Field2,Field3
1,NEW&\/&NEW,4567
3,XYZ,7890
2021-11-24 11:13:43

यह काम करता है. बस कुछ संकेत दिए गए, हालांकि: मैं बारे में पता नहीं था इससे पहले कि इस सवाल का जवाब ` के [^,]*` लेकिन अगर sed को बदलने में सक्षम है के लिए एक विशिष्ट सेल, फिर हम क्यों कर रहे हैं सहित [^,]* . मैं कोशिश की थी sed -Ei "$rownum s/$newvalue/$col" file.csv और इसे फेंक दिया एक त्रुटि के बारे में अधिक जानते हैं । किसी संसाधन को पढ़ने के लिए पर उपयोगी हो जाएगा के रूप में अच्छी तरह से.
Helium

हम की जरूरत है ` [^,]*` क्योंकि यह क्या है परिभाषित करता है क्या एक सेल है. sed नहीं है एक सीएसवी प्रोसेसर, यह एक किसी भी पाठ प्रोसेसर है । तो इसे का ज्ञान नहीं है क्या कहते हैं आप एक सेल है. हम बताना चाहिए । Sed विकल्प आदेश (s) में समझाया गया है गहरा विवरण में sed मैनुअल है कि आप आसानी से मिल जाएगा (यदि आप कर रहे हैं के तहत जीएनयू/लिनक्स या macOS की कोशिश man sed या, और भी बेहतर, info sed). विकल्प कमान आप की कोशिश की है, वाक्य रचना गलत है, इस प्रकार की त्रुटि है ।
Renaud Pacalet

हाँ, है कि अधिक समझ में आता है अब, जब यह डाल की तरह है कि.
Helium
1

के साथ sed, कैसे के बारे में:

#!/bin/bash

newvalue=3
rownum=4
col=1

sed -i -E "${rownum} s/(([^,]+,){$((col-1))})[^,]+/\\1${newvalue}/" file.csv

परिणाम के file.csv

Header,1
Field1,Field2,Field3
1,ABC,4567
3,XYZ,7890
  • ${rownum} मैच लाइन नंबर.
  • (([^,]+,){n}) मैच के एन-समय की पुनरावृत्ति की गैर-अल्पविराम अक्षर के द्वारा पीछा किया, एक अल्पविराम. तो यह होना चाहिए substring लक्ष्य से पहले (के लिए प्रतिस्थापित किया जा सकता है) स्तंभ द्वारा बताए nकरने के लिए col - 1.
2021-11-24 07:21:19

भले ही यह काम करता है, यह नहीं है एक थोड़ा और अधिक जटिल तरीके से काम करने के लिए कैसे की तुलना में Renauld के जवाब. की तरह क्यों करते हैं हम की जरूरत है मैच के लिए एन-बार पुनरावृत्ति कर सकते हैं अगर हम इसके बजाय सीधे यह जगह? फिर भी उपयोगी
Helium
0

चलो कोशिश करते हैं को लागू करने के लिए sed कमान

पर विचार हमें एक नमूना CSV फ़ाइल में निम्न सामग्री:

$ cat file

Solaris,25,11
Ubuntu,31,2
Fedora,21,3
LinuxMint,45,4
RedHat,12,5
  1. को दूर करने के लिए 1 क्षेत्र या स्तंभ :
$ sed 's/[^,]*,//' file

25,11
31,2
21,3
45,4
12,5

यह नियमित अभिव्यक्ति खोज के लिए एक दृश्य के गैर-अल्पविराम([^,]*) वर्ण और उन्हें हटाता में जो परिणाम 1 क्षेत्र में हो रही हटा दिया ।

  1. प्रिंट करने के लिए केवल पिछले क्षेत्र में, या दूर के सभी क्षेत्रों को छोड़कर पिछले क्षेत्र:
$ sed 's/.*,//' file

11
2
3
4
5

इस regex निकालता है सब कुछ जब तक पिछले अल्पविराम(.*,) में जो परिणाम को हटाने के सभी क्षेत्रों को छोड़कर पिछले क्षेत्र है.

  1. प्रिंट करने के लिए केवल 1 क्षेत्र:
$ sed 's/,.*//' file

Solaris
Ubuntu
Fedora
LinuxMint
RedHat

इस regex(,.*) को हटा अक्षर से शुरू 1 अल्पविराम जब तक अंत में जिसके परिणामस्वरूप को हटाने के सभी क्षेत्रों को छोड़कर पिछले क्षेत्र है.

  1. हटाने के लिए 2 क्षेत्र:
$ sed 's/,[^,]*,/,/' file

Solaris,11
Ubuntu,2
Fedora,3
LinuxMint,4
RedHat,5

Regex (,[^,]*,) खोजों के लिए एक अल्पविराम और पात्रों के अनुक्रम के द्वारा पीछा किया, एक अल्पविराम में जो परिणाम मिलान 2 कॉलम, और जगह यह पैटर्न मिलान के साथ सिर्फ एक अल्पविराम है, अंत में समाप्त हटाने 2 कॉलम.

नोट: नष्ट करने के लिए खेतों के बीच में हो जाता है और अधिक मुश्किल में एसईडी के बाद से हर क्षेत्र में किया जा करने के लिए मिलान सचमुच.

  1. प्रिंट करने के लिए केवल 2 क्षेत्र:
$ sed 's/[^,]*,\([^,]*\).*/\1/' file

25
31
21
45
12

Regex से मेल खाता है, पहला क्षेत्र है, दूसरा क्षेत्र और बाकी है, हालांकि समूहों 2 क्षेत्र अकेले. पूरी लाइन है अब के साथ प्रतिस्थापित 2 क्षेत्र(\1), इसलिए केवल 2 क्षेत्र में प्रदर्शित किया जाता है.

  1. केवल प्रिंट लाइनों में जो अंतिम स्तंभ है एक एकल अंकों की संख्या:
$ sed -n '/.*,[0-9]$/p' file

Ubuntu,31,2
Fedora,21,3
LinuxMint,45,4
RedHat,12,5

Regex (,[0-9]$) की जाँच के लिए एक एकल अंक में पिछले क्षेत्र और p आदेश प्रिंट लाइन से मेल खाता है जो इस हालत है ।

  1. नंबर करने के लिए सभी लाइनों फ़ाइल में:
$ sed = file | sed 'N;s/\n/ /'

1 Solaris,25,11
2 Ubuntu,31,2
3 Fedora,21,3
4 LinuxMint,45,4
5 RedHat,12,5

इस का अनुकरण है बिल्ली -एन कमान. ऑक करता है, यह आसानी से उपयोग विशेष चर NR. को '=' की कमान sed देता है लाइन की संख्या हर पंक्ति के द्वारा पीछा लाइन में ही है । Sed उत्पादन पहुंचाया है दूसरे करने के लिए sed आदेश में शामिल होने के लिए हर 2 पंक्तियाँ.

  1. पिछले बदलने के द्वारा क्षेत्र 99 अगर 1 क्षेत्र है 'उबन्टु':
$ sed 's/\(Ubuntu\)\(,.*,\).*/\1\299/' file

Solaris,25,11
Ubuntu,31,99
Fedora,21,3
LinuxMint,45,4
RedHat,12,5

इस regex से मेल खाता 'उबन्टु' और अंत तक पिछले छोड़कर स्तंभ और समूहों में से प्रत्येक के रूप में उन्हें अच्छी तरह से. में प्रतिस्थापन भाग के लिए, 1 और 2 के समूह के साथ-साथ नए नंबर 99 प्रतिस्थापित है.

  1. हटाना 2 क्षेत्र अगर 1 क्षेत्र है 'RedHat':
$ sed 's/\(RedHat,\)[^,]*\(.*\)/\1\2/' file

Solaris,25,11
Ubuntu,31,2
Fedora,21,3
LinuxMint,45,4
RedHat,,5

1 क्षेत्र 'RedHat', 2 क्षेत्र और शेष क्षेत्रों में वर्गीकृत कर रहे हैं, और प्रतिस्थापन के साथ किया जाता है, केवल 1 और पिछले समूह , resuting में हो रही 2 क्षेत्र नष्ट कर दिया ।

  1. सम्मिलित करने के लिए, एक नया स्तंभ पर अंत(अंतिम स्तंभ) :
$ sed 's/.*/&,A/' file

Solaris,25,11,A
Ubuntu,31,2,A
Fedora,21,3,A
LinuxMint,45,4,A
RedHat,12,5,A

Regex (.*) मैच पूरी लाइन और यह जगह के साथ लाइन में ही (&) और नए क्षेत्र.

  1. सम्मिलित करने के लिए, एक नए स्तंभ की शुरुआत में(1 कॉलम):
$ sed 's/.*/A,&/' file

A,Solaris,25,11
A,Ubuntu,31,2
A,Fedora,21,3
A,LinuxMint,45,4
A,RedHat,12,5

वही के रूप में पिछले उदाहरण के लिए, बस लाइन मिलान के द्वारा पीछा किया जाता है नया स्तंभ

मुझे आशा है कि यह मदद मिलेगी. मुझे पता है अगर आप की जरूरत का उपयोग करने के लिए ऑक या किसी भी अन्य आदेश. धन्यवाद

2021-11-24 07:36:29

धन्यवाद विस्तृत विवरण के लिए, लेकिन दुर्भाग्य से यह नहीं करता है, इस मुद्दे को हल हाथ में है ।
Helium

अन्य भाषाओं में

यह पृष्ठ अन्य भाषाओं में है

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................

इस श्रेणी में लोकप्रिय

लोकप्रिय सवाल इस श्रेणी में