Row swap for multiple files
-
Something like the following could work…I encourage you to make a backup of your 4000 files before trying it!
Use the “Replace in Files” feature.
Find what: (?-s)((?:.*\R){X-1})(.*\R)((?:.*\R){Y-X-1})(.*\R)(?s)(.*) Replace with: \1\4\3\2\5 Search mode: Regular expression
Where X is the lower line number of the lines to swap and Y is the higher line number.
Here’s a concrete example for swapping lines 3 and 9:
Find what: (?-s)((?:.*\R){2})(.*\R)((?:.*\R){5})(.*\R)(?s)(.*) Replace with: \1\4\3\2\5 Search mode: Regular expression
-
@Sascheya-Dragon-Shikamaru
Based on the number of files you say are involved, I’m going to go ahead and say that using NPP isn’t the best way to achieve your goal.We really need more information to help you unless you are happy with an answer like, “No, you don’t have to change all the files manually.”
Please describe your needs in detail. How are the lines to be swapped identified? Are they always particular line numbers or does it depend on the text contained on the lines? Is there a single pair of lines in each file? Are there varied numbers of pairs of lines in the files? We need to know that type of information.
-
Jim is right, of course. Earlier I just answered the simplest case, where the rows to swap occur in the same places in each file. This may very well NOT be the case.
-
Hello, Sascheya Dragon Shikamaru and Scott,
Sascheya Dragon Shikamaru, just SKIP this post, as I was totally wrong about my proposed regex. It does NOT work at all ! Thanks to Scott to pointing out the problem !
Waaaouu ! Scott, you become a regex master : non-capturing groups, the two modifiers
(?s-)
and(?s)
and the\R
syntax for line-breaks ;-))Looking at your regex, I had an intuition , that I verified and it worked fine ! Indeed, we just need of the block of lines, beginning at line
X
and ending at lineY
, included ! We don’t care about any text, which is located before and/or after that block !So I would use the
\K
syntax to “forget” the first lines ( your group 1 ) and just NOT add the remainder of each file scanned ( your group 5 ) ! This should improve the execution of the regex !So the general regex, with the Regular expression mode enabled, could be shortened :
SEARCH
(?-s)(?:.*\R){X-1}\K(.*\R)((?:.*\R){Y-X-1})(.*\R)
DONT’WORK : Refer to the correct Scott’s regex, above !REPLACE
\3\2\1
Where
X
is the lower line number of the first line to swap andY
is the higher line number.of the second line to swapAnd for swapping, as you said, line 3 and 9, the appropriate regex would be :
SEARCH
(?-s)(?:.*\R){2}\K(.*\R)((?:.*\R){5})(.*\R)
DONT’WORK : Refer to the correct Scott’s regex, above !
Like you, I think that Jim’s post is really sensible. So, Sascheya Dragon Shikamaru, try to provide some more information : it would just help us to avoid some dead-ends and improve the quality of our answers, to solve your problem !
Cheers,
guy038
-
Not a master, certainly, but just dangerous enough with regex to get done what I need to, and maybe take a try at the more interesting posts here (while you are sleeping in France – don’t worry, still plenty for you to tackle!).
So I tried your new regex with “Replace in Files” and I found that it suffers from a problem that one of my first tries also had: It swaps more than lines 3 and 9 – it also swaps lines 12 and 18, lines 21 and 27, lines 30 and 36, …, and so on. That is the reason I used (.*) at the end of my search regex along with \5 at the end of the replace text – it prevents this extra swapping, since the “spec” (that maybe I inferred) was to only swap one pair of lines.
-
Hi, Scott,
Do you know ? My test file contained 12 lines only ( just enough to see the swapping of lines 3 and 9 !! ) So, I did not notice the obvious side-effect :-(( Ahhhhhhhhh !
Indeed, your solution is the only way to avoid further matches, in the same file :-)) So, I just confirm : a Regex’s Master !
Of course, I could, still, use the
\K
syntax just to avoid your first group 1. But it look less elegant than your regex !Cheers,
guy038
Of course, I’m about to update my previous post !
-
Hello,
First of all , I wana thank all of your for the responses, Ive learned quite a few things.
Second, you guys are right I should have add’ed some more details, sorry for the troble, reading this remembered me that Ive got another problem.Long story short , 1 file = 1 land parcel that can have from 1 to many owners, <Person>
some smart ass translated: first name = the family name and the second = your name that you get at your birth.
And now I need to swap the content of <FIRSTNAME> </FIRSTNAME> and <LASTNAME> </LASTNAME> .
My original trought was , find and replace FIRSTNAME with SOMENAME , then replace LASTNAME with FIRSTNAME, and after that SOMENAME with LASTNAME. And after all that to swap the rows.
But… now Ive remembered there are cases where there are more then one 1 owner, and thats not gona work.
Here are some examples:
-with 1 owner: https://github.com/uZuRu17/origina_cgxml/blob/master/example
-with 4 owners: https://github.com/uZuRu17/origina_cgxml/blob/master/example.gitignore -
It isn’t immediately obvious to me why your original thought will not work for multiple owners, as long as you replace ALL occurrences at once.
Still, with ~4K files to do this on, I would think some sort of command line-based tool would be preferable to using a GUI-based tool like NPP. Something like the UNIX sed utility, for example, or some scripting language.
-
I took a quick look at your data. As it is XML, what about swapping the FIRSTNAME and LASTNAME tags and leaving the data in-place? But I think changing the tags is easier, especially since I saw some places in your data where there was a (empty) <LASTNAME /> tag instead of a <LASTNAME>foobar</LASTNAME> grouping.
Anyway, you could swap all FIRSTNAME and LASTNAME in your files using this Replace in Files operation:
Find what: (FIRSTNAME)|(LASTNAME) Repl with: (?1LASTNAME)(?2FIRSTNAME) Mode: Regular expression
Again, make sure you have a backup of your data before you entrust it to the Replace in Files feature.
-
if you do not feel comfortable with regex, like me
do search for <~~~ in all your files
this is a “flag sequence”, so make sure that it is not already thereif not found then go on.
Find what: <FIRSTNAME>
Repl with: <~~~LASTNAME>
Mode: Normal or ExtendedFind what: <LASTNAME>
Repl with: <~~~FIRSTNAME>Find what: </FIRSTNAME>
Repl with: <~~~/LASTNAME>Find what: </LASTNAME>
Repl with: <~~~/FIRSTNAME>Find what: <FIRSTNAME />
Repl with: <~~~LASTNAME />Find what: <LASTNAME />
Repl with: <~~~FIRSTNAME />now check for any missed ones
Find what: <FIRSTNAME
Find what: <LASTNAMEnow delete the ~~~
Find what: <~~~
Repl with: <you could reduce number of steps
Find what: FIRSTNAME>
Repl with: LASTNAME~~~>Find what: LASTNAME>
Repl with: FIRSTNAME~~~>those two would cover <LASTNAME> and </LASTNAME>
anyway i hope that it helps you or anyone else